作者|B. Chen
編譯|VK
來源|Towards Datas Science

Pandas是一個驚人的庫,它包含了大量用于操作資料的內置函式,其中,transform()在處理行或列時非常有用,
在本文中,我們將介紹以下最常用的Pandas transform()用途:
-
轉換值
-
組合groupby()
-
過濾資料
-
在組級別處理缺失值
請查看我的Github repo以獲取源代碼;https://github.com/BindiChen/machine-learning/blob/master/data-analysis/013-pandas-transform/pandas-transform.ipynb
1.轉換值
我們來看看pd.transform(func, axis=0)
-
第一個引數func指定用于操作資料的函式,它可以是函式、字串函式名、函式串列或軸標簽->函式的字典
-
第二個引數軸指定函式應用于哪個軸,0表示對每列應用func,1表示對每行應用func,
讓我們看看transform()是如何在一些示例的幫助下作業的,
函式
我們可以把函式傳遞給func,例如
df = pd.DataFrame({'A': [1,2,3], 'B': [10,20,30] })
def plus_10(x):
return x+10
df.transform(plus_10)

也可以使用lambda運算式,下面是plus_10()的lambda等價形式:
df.transform(lambda x: x+10)
字串函式
我們可以將任何有效的Pandas字串函式傳遞給func,例如'sqrt':
df.transform('sqrt')

函式串列
func可以是函式的串列,例如,來自NumPy的sqrt和exp:
df.transform([np.sqrt, np.exp])

軸標簽->函式的字典
func可以是軸標簽->函式的字典,例如
df.transform({
'A': np.sqrt,
'B': np.exp,
})

2.組合groupby()
Pandas transform()最引人注目的用法之一是組合groupy()結果,
讓我們通過一個例子來看看這是如何作業的,假設我們有一個關于連鎖餐廳的資料集
df = pd.DataFrame({
'restaurant_id': [101,102,103,104,105,106,107],
'address': ['A','B','C','D', 'E', 'F', 'G'],
'city': ['London','London','London','Oxford','Oxford', 'Durham', 'Durham'],
'sales': [10,500,48,12,21,22,14]
})

我們可以看到,每個城市都有多家餐廳在銷售,我們想知道“每一家餐廳在本市的銷售額占比是多少”,預期輸出為:

在這個計算中最棘手的部分是,我們需要得到一個城市的總銷售額,并將其合并到資料中,以得到百分比,
有兩種解決方案:
-
groupby()、apply()和merge()
-
groupby()和transform()
解決方案1:groupby()、apply()和merge()
第一種解決方案是使用groupby()分割資料,并使用apply()聚合每個組,然后使用merge()將結果合并回原始資料幀中
第1步:使用groupby()和apply()計算城市銷售總額
city_sales = df.groupby('city')['sales']
.apply(sum).rename('city_total_sales').reset_index()

groupby('city')通過在city列上分組來拆分資料,對于每個組,函式sum應用于sales列,以計算每個組的總和,最后,將新列重命名為city_total_sales并重置索引(注意:需要reset_inde()來清除groupby('city')生成的索引,
此外,Pandas還有一個內置的sum()函式,下面是Pandas sum()的等效函式:
city_sales = df.groupby('city')['sales']
.sum().rename('city_total_sales').reset_index()
第2步:使用merge()函式合并結果
df_new = pd.merge(df, city_sales, how='left')

使用merge()和left outer join的how='left'將組結果合并回到原始的DataFrame中
第3步:計算百分比
最后,可以計算并格式化百分比,
df_new['pct'] = df_new['sales'] / df_new['city_total_sales']
df_new['pct'] = df_new['pct'].apply(lambda x: format(x, '.2%'))

這當然是我們的作業,但這是一個多步驟的程序,需要額外的代碼才能以我們需要的形式獲取資料,
我們可以使用transform()函式有效地解決這個問題
解決方案2:groupby()和transform()
這個解決方案改變了游戲規則,一行代碼就可以解決應用和合并問題,
步驟1:使用groupby()和transform()計算城市銷售總額
轉換函式在執行轉換后保留與原始資料集相同數量的項,因此,使用groupby后跟transform(sum)的單行步驟回傳相同的輸出,
df['city_total_sales'] = df.groupby('city')['sales']
.transform('sum')

第2步:計算百分比
最后,這和求百分比是一樣的,
df['pct'] = df['sales'] / df['city_total_sales']
df['pct'] = df['pct'].apply(lambda x: format(x, '.2%'))
3.過濾資料
transform()也可用于過濾資料,在這里,我們試圖獲得該市總銷售額超過40的記錄
df[df.groupby('city')['sales'].transform('sum') > 40]

4.在組級別處理丟失的值
Pandas transform()的另一個用法是在組級別處理丟失的值,讓我們用一個例子來看看這是如何作業的,
這里有一個資料幀供演示
df = pd.DataFrame({
'name': ['A', 'A', 'B', 'B', 'B', 'C', 'C', 'C'],
'value': [1, np.nan, np.nan, 2, 8, 2, np.nan, 3]
})

在上面的示例中,可以按名稱將資料分成三組,每個組都缺少值,替換缺失值的常見解決方案是用平均值替換NaN,
讓我們看看每組的平均值,
df.groupby('name')['value'].mean()
name
A 1.0
B 5.0
C 2.5
Name: value, dtype: float64
在這里,我們可以使用transform()將缺少的值替換為組平均值,
df['value'] = df.groupby('name')
.transform(lambda x: x.fillna(x.mean()))

你可以在我的Github上獲取源代碼:https://github.com/BindiChen/machine-learning/blob/master/data-analysis/013-pandas-transform/pandas-transform.ipynb
原文鏈接:https://towardsdatascience.com/when-to-use-pandas-transform-function-df8861aa0dcf
歡迎關注磐創AI博客站:
http://panchuang.net/
sklearn機器學習中文官方檔案:
http://sklearn123.com/
歡迎關注磐創博客資源匯總站:
http://docs.panchuang.net/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/155058.html
標籤:其他
