(特徵工程實戰)ML最實用的資料預處理與特徵工程常用函式!

程式碼屆的小白發表於2020-12-13

這裡給大家一一列舉在資料預處理和特徵工程中經常用到的python函式模組,非常實用!
在這裡插入圖片描述

1.groupby函式

在使用python進行資料分析的過程中,採用groupby函式對資料進行分組是一項很常用的操作。

python中groupby函式主要的作用是進行資料的分組以及分組後地組內運算!

對於資料的分組和分組運算主要是指groupby函式的應用,具體函式的規則如下:df[](指輸出資料的結果屬性名稱).groupby([df[屬性],df[屬性])(指分類的屬性,資料的限定定語,可以有多個).mean()(對於資料的計算方式——函式名稱)

示例:

data.groupby(group)[feature].agg([sum, min, max, np.mean]).reset_index()
#根據gruop分組,並計算特徵feature的和、最小、最大和平均值資料

根據類別分組,然後計算每個類別下的feature特徵的和、最小、最大和平均值。(就是說:按照類別分組,每個資料在組內的情況)

group_list = ['HYZK', 'ZHIYE', 'ZHICHEN', ...]
num_feature_list = ['GRYJCE', 'DKFFE', 'DKLL', ...]                   
for group in group_list:
    for feature in num_feature_list:
     #根據類別分組,然後計算每個類別下的feature特徵的和、最小、最大和平均值。
        tmp = data.groupby(group)[feature].agg([sum, min, max, np.mean]).reset_index()
        tmp = pd.merge(data, tmp, on=group, how='left')
        data['{}-mean_gb_{}'.format(feature, group)] = data[feature] - tmp['mean']
        data['{}-min_gb_{}'.format(feature, group)] = data[feature] - tmp['min']
        data['{}-max_gb_{}'.format(feature, group)] = data[feature] - tmp['max']
        data['{}/sum_gb_{}'.format(feature, group)] = data[feature] / tmp['sum']  

groupby()的常見用法:
在這裡插入圖片描述

這是由於變數grouped是一個GroupBy物件,它實際上還沒有進行任何計算,只是含有一些有關分組鍵df[‘key1’]的中間資料而已,然後我們可以呼叫配合函式(如:.mean()方法)來計算分組平均值等。
  因此,一般為方便起見可直接在聚合之後+“配合函式”,預設情況下,所有數值列都將會被聚合,雖然有時可能會被過濾為一個子集。
  一般,如果對df直接聚合時,
df.groupby([df[‘key1’],df[‘key2’]]).mean()(分組鍵為:Series)與df.groupby([‘key1’,‘key2’]).mean()(分組鍵為:列名)是等價的,輸出結果相同。
  但是,如果對df的指定列進行聚合時,
df[‘data1’].groupby(df[‘key1’]).mean()(分組鍵為:Series),唯一方式。
此時,直接使用“列名”作分組鍵,提示“Error Key”。   
注意:分組鍵中的任何缺失值都會被排除在結果之外。

groupby()的配合函式:
在這裡插入圖片描述

1)根據key1鍵對data1列資料聚合
df.groupby('key1')['data1'].mean()
#或者
df['data1'].groupby(df['key1']).mean()2)當對多列資料如data1和data2根據某個鍵入key1聚合分組時,組引入列表['data1','data2'],此處對data2外加中括號是一個意思,只是影響輸出格式。
根據key1鍵對data1和data2列資料聚合
df.groupby('key1')[['data1','data2']].mean()
#或者
df[['data1','data2']].groupby(df['key1']).mean()3)根據多個鍵key1、key2對data2列資料聚合
df.groupby(['key1','key2'])['data2'].mean()
#或者
df['data2'].groupby([df['key1'],df['key2']]).mean()

2.map函式

會根據提供的函式對指定序列做對映。
示例:

data['XUELI'].value_counts()
結果:99出現了54994次,0出現了699    54994  
0         6
Name: XUELI, dtype: int64
data['XUELI'].map(data['XUELI'].value_counts())
結果:99的全部對映為次數54994,0的全部對映為次數6
0        54994
1        54994
2        54994
3        54994
4        54994
         ...  
54995    54994
54996    54994
54997    54994
54998    54994
54999    54994
Name: XUELI, Length: 55000, dtype: int64

3.transfrom函式

參考文章
在這裡插入圖片描述

4.merge函式

引數格式

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
         left_index=False, right_index=False, sort=True,
         suffixes=('_x', '_y'), copy=True, indicator=False,
         validate=None)

引數如下:

  • left:拼接的左側DataFrame物件

  • right: 拼接的右側DataFrame物件

  • on: 要加入的列或索引級別名稱。 必須在左側和右側DataFrame物件中找到。如果未傳遞且left_index和right_index為False,則DataFrame中的列的交集將被推斷為連線鍵。

  • left_on:左側DataFrame中的列或索引級別用作鍵。 可以是列名,索引級名稱,也可以是長度等於DataFrame長度的陣列。

  • right_on: 左側DataFrame中的列或索引級別用作鍵。 可以是列名,索引級名稱,也可以是長度等於DataFrame長度的陣列。

  • eft_index: 如果為True,則使用左側DataFrame中的索引(行標籤)作為其連線鍵。
    對於具有MultiIndex(分層)的DataFrame,級別數必須與右側DataFrame中的連線鍵數相匹配。

  • right_index: 與left_index功能相似。

  • how: One of ‘left’, ‘right’, ‘outer’, ‘inner’.預設inner。inner是取交集,outer取並集。比如left[‘A’,‘B’,‘C’];right[’'A,‘C’,‘D’];inner取交集的話,left中出現的A會和right中出現的買一個A進行匹配拼接,如果沒有是B,在right中沒有匹配到,則會丟失。'outer’取並集,出現的A會進行一一匹配,沒有同時出現的會將缺失的部分新增缺失值。

  • sort: 按字典順序通過連線鍵對結果DataFrame進行排序。 預設為True,設定為False將在很多情況下顯著提高效能。

  • suffixes: 用於重疊列的字串字尾元組。 預設為(‘x’,’ y’)。

  • copy: 始終從傳遞的DataFrame物件複製資料(預設為True),即使不需要重建索引也是如此。

  • indicator:將一列新增到名為_merge的輸出DataFrame,其中包含有關每行源的資訊。_merge是分類型別,並且對於其合併鍵僅出現在“左”DataFrame中的觀察值,取得值為left_only,對於其合併鍵僅出現在“右”DataFrame中的觀察值為right_only,並且如果在兩者中都找到觀察點的合併鍵,則為left_only。

示例程式碼:

import pandas as pd

left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                       'A': ['A0', 'A1', 'A2', 'A3'],
                       'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                        'C': ['C0', 'C1', 'C2', 'C3'],
                        'D': ['D0', 'D1', 'D2', 'D3']})
result = pd.merge(left, right, on='key')

# on引數傳遞的key作為連線鍵
result
Out[4]: 
    A   B key   C   D
0  A0  B0  K0  C0  D0
1  A1  B1  K1  C1  D1
2  A2  B2  K2  C2  D2
3  A3  B3  K3  C3  D3

Merge method
如果組合鍵沒有出現在左表或右表中,則連線表中的值將為NA。
在這裡插入圖片描述

a1 = pd.DataFrame({
                    'a': [1, 1, 2, 2, 2, 6, 7, 8, 10],
                    'b': [1, 2, 3, 4, 5, 6, 7, 8, 9],
                    'c': [1, 2, 3, 4, 5, 6, 7, 8, 9]
                  })
a2 = pd.DataFrame({
                    'a': [1, 1, 2, 4, 5, 6, 7, 8, 11],
                    'b': ['w', 'e', '2對應的出現3次', 4, 5, 6, 7, 8, 9],
                    'c': ['d', 'g', '2對應的出現3次', 4, 5, 6, 7, 8, 9]
                  })
a3 = pd.merge( left = a1, right = a2, on = ['a'], how = 'left')
print(a3)
#      a  b_x  c_x       b_y       c_y
# 0    1    1    1         w         d
# 1    1    1    1         e         g
# 2    1    2    2         w         d
# 3    1    2    2         e         g
# 4    2    3    3  2對應的出現3次  2對應的出現3次
# 5    2    4    4  2對應的出現3次  2對應的出現3次
# 6    2    5    5  2對應的出現3次  2對應的出現3次
# 7    6    6    6         6         6
# 8    7    7    7         7         7
# 9    8    8    8         8         8
# 10  10    9    9       NaN       NaN

比賽中用到示例:

train_data = pd.merge(base_info, entprise_info, on='id')
train_data = pd.merge(train_data, other_info, on='id', how='left')

train_data = pd.merge(train_data, news_info_df, on='id', how='left')
train_data = pd.merge(train_data, tax_info_df, on='id', how='left')
train_data = pd.merge(train_data, annual_report_info_df, on='id', how='left')
train_data = pd.merge(train_data, change_info_df, on='id', how='left')

5.reset_index函式

意思就是重新排序

通過reset_index()方法我們可以重置索引,drop引數為True時,直接丟棄原來的
索引,否則原來的索引新生成一列名為'index'的列:
df.reset_index(inplace=True,drop=True)

6.astype函式

astype()函式可用於轉化dateframe某一列的資料型別

如下將dateframe某列的str型別轉為int,注意astype()沒有replace=True的用法,想要在原資料上修改,要寫成如下形式。
注意只有當該列的字串全是由純數字構成時才可以這樣寫,如果混有字母,會報錯:ValueError: invalid literal for int() with base 10:

示例:
```python
cat_col = ['HYZK', 'ZHIYE', 'ZHICHEN','DWJJLX', 'DWSSHY', 'GRZHZT']
X_train[cat_col] = X_train[cat_col].astype('category')
X_test[cat_col] = X_test[cat_col].astype('category')

7.duplicated函式

用duplicated( )函式判斷
C.duplicated()
DataFrame 刪除重複資料 duplicated函式
在這裡插入圖片描述

8.nunique()函式

Pandas nunique() 用於獲取唯一值的統計次數。

#訓練集中的使用者數量為20w
trn_click.user_id.nunique()

9.apply函式

apply函式是pandas裡面所有函式中自由度最高的函式。該函式如下:

DataFrame.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)

該函式最有用的是第一個引數,這個引數是函式,相當於C/C++的函式指標。

這個函式需要自己實現,函式的傳入引數根據axis來定,比如axis = 1,就會把一行資料作為Series的資料結構傳入給自己實現的函式中,我們在函式中實現對Series不同屬性之間的計算,返回一個結果,則apply函式會自動遍歷每一行DataFrame的資料,最後將所有結果組合成一個Series資料結構並返回。

  1. 該函式最有用的是第一個引數,這個引數是函式,相當於C/C++的函式指標。
  2. 這個函式需要自己實現,函式的傳入引數根據axis來定,比如axis = 1,就會把一行資料作為Series的資料 結構傳入給自己實現的函式中,我們在函式中實現對Series不同屬性之間的計算,返回一個結果,則apply函式
    會自動遍歷每一行DataFrame的資料,最後將所有結果組合成一個Series資料結構 並返回。
  3. apply函式常與groupby函式一起使用,如下圖所示 在這裡插入圖片描述
    在這裡插入圖片描述
    示例:
news_info['public_date'] = news_info['public_date'].apply(lambda x: x if '-' in str(x) else np.nan)#處理時間

10.lambda函式

python中lambda函式
lambda是Python預留的關鍵字

lambda函式的特性:

  1. lambda函式是匿名的:所謂匿名函式,通俗地說就是沒有名字的函式。lambda函式沒有名字。
  2. lambda函式有輸入和輸出:輸入是傳入到引數列表argument_list的值,輸出是根據表示式expression計算得到的值。
  3. lambda函式一般功能簡單:單行expression決定了lambda函式不可能完成複雜的邏輯,只能完成非常簡單的功能。由於其實現的功能一目瞭然,甚至不需要專門的名字來說明。

示例:

news_info['public_date'] = news_info['public_date'].apply(lambda x: x if '-' in str(x) else np.nan)#處理時間

參考:
[1]https://zhuanlan.zhihu.com/p/109591980(groupby)
[2]https://www.cnblogs.com/Yanjy-OnlyOne/p/11217802.html(groupby)
[3]https://zhuanlan.zhihu.com/p/86350553(transfrom)
[4]https://blog.csdn.net/brucewong0516/article/details/82707492(merge)
[5]https://www.cnblogs.com/wind666/p/10703064.html(lambda)
記錄時間:2020年12月13日

相關文章