Pandas數(shù)據(jù)處理實戰(zhàn):福布斯全球上市企業(yè)排行榜數(shù)據(jù)整理

手頭現(xiàn)在有一份福布斯2016年全球上市企業(yè)2000強排行榜的數(shù)據(jù),但原始數(shù)據(jù)并不規(guī)范,需要處理后才能進(jìn)一步使用。

本文通過實例操作來介紹用pandas進(jìn)行數(shù)據(jù)整理。

照例先說下我的運行環(huán)境,如下:

  • windows 7, 64位
  • python 3.5
  • pandas 0.19.2版本

在拿到原始數(shù)據(jù)后,我們先來看看數(shù)據(jù)的情況,并思考下我們需要什么樣的數(shù)據(jù)結(jié)果。

下面是原始數(shù)據(jù):

在本文中,我們需要以下的初步結(jié)果,以供以后繼續(xù)使用。

可以看到,原始數(shù)據(jù)中,跟企業(yè)相關(guān)的數(shù)據(jù)中(“Sales”,“Profits”,“Assets”,“Market_value”),目前都是不是可以用來計算的數(shù)字類型。

原始內(nèi)容中包含貨幣符號”$“,“-”,純字母組成的字符串以及其他一些我們認(rèn)為異常的信息。更重要的是,這些數(shù)據(jù)的單位并不一致。分別有以“B”(Billion,十億)和“M”(Million,百萬)表示的。在后續(xù)計算之前需要進(jìn)行單位統(tǒng)一。

1 處理方法 Method-1

首先想到的處理思路就是將數(shù)據(jù)信息分別按十億('B')和百萬('M')進(jìn)行拆分,分別進(jìn)行處理,最后在合并到一起。過程如下所示。

  • 加載數(shù)據(jù),并添加列的名稱
import pandas as pd

df_2016 = pd.read_csv('data_2016.csv', encoding='gbk',header=None)

# 更新列名
df_2016.columns = ['Year', 'Rank', 'Company_cn','Company_en',
                   'Country_en', 'Sales', 'Profits', 'Assets', 'Market_value']

print('the shape of DataFrame: ', df_2016.shape)
print(df_2016.dtypes)
df_2016.head(3)
  • 獲取單位為十億('B')的數(shù)據(jù)
# 數(shù)據(jù)單位為 B的數(shù)據(jù)(Billion,十億)
df_2016_b = df_2016[df_2016['Sales'].str.endswith('B')]
print(df_2016_b.shape)
df_2016_b
  • 獲取單位為百萬('M')的數(shù)據(jù)
# 數(shù)據(jù)單位為 M的數(shù)據(jù)(Million,百萬)
df_2016_m = df_2016[df_2016['Sales'].str.endswith('M')]
print(df_2016_m.shape)
df_2016_m

這種方法理解起來比較簡單,但操作起來會比較繁瑣,尤其是如果有很多列數(shù)據(jù)需要處理的話,會花費很多時間。

進(jìn)一步的處理,我這里就不描述了。當(dāng)然,各位可以試試這個方法。

下面介紹稍微簡單一點的方法。

2 處理方法 Method-2

2.1 加載數(shù)據(jù)

第一步還是加載數(shù)據(jù),跟Method-1是一樣的。

下面來處理'Sales'列

2.2 替換相關(guān)的異常字符

首先是替換相關(guān)的異常字符,包括美元的貨幣符號'$',純字母的字符串'undefined',以及'B'。 這里,我們想統(tǒng)一把數(shù)據(jù)的單位整理成十億,所以'B'可以直接進(jìn)行替換。而'M'需要更多的處理步驟。

2.3 處理'M'相關(guān)的數(shù)據(jù)

處理含有百萬“M”為單位的數(shù)據(jù),即以“M”結(jié)尾的數(shù)據(jù),思路如下:

(1)設(shè)定查找條件mask;

(2)替換字符串“M”為空值

(3)用pd.to_numeric()轉(zhuǎn)換為數(shù)字

(4)除以1000,轉(zhuǎn)換為十億美元,與其他行的數(shù)據(jù)一致

上面兩個步驟相關(guān)的代碼如下:

# 替換美元符號
df_2016['Sales'] = df_2016['Sales'].str.replace('$','')

# # 查看異常值,均為字母(“undefined”)
# df_2016[df_2016['Sales'].str.isalpha()]

# 替換異常值“undefined”為空白
# df_2016['Sales'] = df_2016['Sales'].str.replace('undefined','')
df_2016['Sales'] = df_2016['Sales'].str.replace('^[A-Za-z]+$','')

# 替換符號十億美元“B”為空白,數(shù)字本身代表的就是十億美元為單位
df_2016['Sales'] = df_2016['Sales'].str.replace('B','')


# 處理含有百萬“M”為單位的數(shù)據(jù),即以“M”結(jié)尾的數(shù)據(jù)
# 思路:
# (1)設(shè)定查找條件mask;
# (2)替換字符串“M”為空值
# (3)用pd.to_numeric()轉(zhuǎn)換為數(shù)字
# (4)除以1000,轉(zhuǎn)換為十億美元,與其他行的數(shù)據(jù)一致
mask = df_2016['Sales'].str.endswith('M')
df_2016.loc[mask, 'Sales'] = pd.to_numeric(df_2016.loc[mask, 'Sales'].str.replace('M', ''))/1000

df_2016['Sales'] = pd.to_numeric(df_2016['Sales'])
print('the shape of DataFrame: ', df_2016.shape)
print(df_2016.dtypes)
df_2016.head(3)

用同樣類似的方法處理其他列

可以看到,這個方法比第一種方法還是要方便很多。當(dāng)然,這個方法針對DataFrame的每列數(shù)據(jù)都要進(jìn)行相關(guān)的操作,如果列數(shù)多了,也還是比較繁瑣的。

有沒有更方便一點的方法呢。 答案是有的。

3 處理方法 Method-3

在Method-2的基礎(chǔ)上,將處理方法寫成更通用的數(shù)據(jù)處理函數(shù),根據(jù)數(shù)據(jù)的結(jié)構(gòu),拓展更多的適用性,則可以比較方便的處理相關(guān)數(shù)據(jù)。

3.1 加載數(shù)據(jù)

第一步還是加載數(shù)據(jù),跟Method-1是一樣的。

3.2 編寫數(shù)據(jù)處理的自定義函數(shù)

參考Method-2的處理過程,編寫數(shù)據(jù)處理的自定義函數(shù)'pro_col',并在Method-2的基礎(chǔ)上拓展其他替換功能,使之適用于這四列數(shù)據(jù)(“Sales”,“Profits”,“Assets”,“Market_value”)。

函數(shù)編寫的代碼如下:

def pro_col(df, col):   
    # 替換相關(guān)字符串,如有更多的替換情形,可以自行添加
    df[col] = df[col].str.replace('$','')
    df[col] = df[col].str.replace('^[A-Za-z]+$','')
    df[col] = df[col].str.replace('B','')

    # 注意這里是'-$',即以'-'結(jié)尾,而不是'-',因為有負(fù)數(shù)
    df[col] = df[col].str.replace('-$','')
    df[col] = df[col].str.replace(',','')

    # 處理含有百萬“M”為單位的數(shù)據(jù),即以“M”結(jié)尾的數(shù)據(jù)
    # 思路:
    # (1)設(shè)定查找條件mask;
    # (2)替換字符串“M”為空值
    # (3)用pd.to_numeric()轉(zhuǎn)換為數(shù)字
    # (4)除以1000,轉(zhuǎn)換為十億美元,與其他行的數(shù)據(jù)一致
    mask = df[col].str.endswith('M')
    df.loc[mask, col] = pd.to_numeric(df.loc[mask, col].str.replace('M',''))/1000

    # 將字符型的數(shù)字轉(zhuǎn)換為數(shù)字類型
    df[col] = pd.to_numeric(df[col])
    return df

3.3 將自定義函數(shù)進(jìn)行應(yīng)用

針對DataFrame的每列,應(yīng)用該自定義函數(shù),進(jìn)行數(shù)據(jù)處理,得到需要的結(jié)果。

pro_col(df_2016, 'Sales')
pro_col(df_2016, 'Profits')
pro_col(df_2016, 'Assets')
pro_col(df_2016, 'Market_value')

print('the shape of DataFrame: ', df_2016.shape)
print(df_2016.dtypes)
df_2016.head()

當(dāng)然,如果DataFrame的列數(shù)特別多,可以用for循環(huán),這樣代碼更簡潔。代碼如下:

cols = ['Sales', 'Profits', 'Assets', 'Market_value']
for col in cols:
    pro_col(df_2016, col)

print('the shape of DataFrame: ', df_2016.shape)
print(df_2016.dtypes)
df_2016.head()

最終處理后,獲得的數(shù)據(jù)結(jié)果如下:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容