當前位置: 首頁>>技術教程>>正文


Pandas使用高級技巧

這篇文章包括一些有用的Pandas技巧,這些技巧有助於在大型數據集上使用Pandas進行有效的預處理和特征工程。

Pandas ufuncs (Universal functions)以及為什麽它們比apply命令好得多

Pandas 有一個apply函數,您幾乎可以將任何函數應用(apply)於列中的所有值。注意apply隻是比python for循環快一點!這就是為什麽推薦使用Pandas內置的 ucfuns 在列上應用預處理任務ucfuns是用C語言實現的一些特定功能(基於numpy庫),因此非常高效。我們將提到的有用的功能包括:.diff,.shift,.cumsum,.cumcount,.str命令(用於字符串),.dt命令(用於日期) ,等等。

數據集示例-暑期活動

我將在如下圖說是的數據集上演示 Pandas 技巧。暑期活動數據集說明:一個人可以在不同的時間戳下進行多項活動。

圖:夏季活動,隨機生成的數據

假設我們的目標是根據給定的數據集預測誰是數據集中最有趣的人:)。

圖:好玩好玩!

1.字符串命令

對於字符串操作,最推薦使用Pandas string 命令(屬於ufuncs)。

例如,您可以使用以下方式將包含一個人的全名的列分為兩列:.str.split, 參數expand = True。

圖:拆分前的名稱列
df[‘name’] = df.name.str.split(" ", expand=True)

圖:拆分後的名稱列

另外,您可以使用.str.replace和一個合適的正則表達式有效地清理任何字符串列。

2. group by和value_counts

group by是一個非常強大的 Pandas 方法。您可以使用以下方式對一列進行分組,並使用value_counts根據該列值計算另一列的值。使用group byvalue_counts我們可以計算每個人進行的活動數量。

df.groupby('name')['activity'].value_counts()

圖:按人員名稱和活動值分組

這就是多索引情況,它是pandas DataFrame中的一個有價值的技巧,它使我們在DataFrame中具有幾個級別的索引層次結構。在這種情況下,人員名稱是索引的級別0,而活動是級別1。

3.Unstack

通過在上麵的代碼中應用unstack,我們還可以為每個人的夏季活動計數。unstack將行切換為列,以將活動計數作為特征值。通過做unstack將索引的最後一級轉換為列。現在,所有活動值將成為DataFrame的列。其中當某人未執行某項活動時,此特征值為Nan。Fillna函數用0填充所有這些缺失值(人員未進行的活動)。

df.groupby('name')['activity'].value_counts().unstack().fillna(0)

圖:列中的活動計數

3. groupby,diff,shift和loc +高效技巧

了解人的活動之間的時差對於預測誰是最有趣的人可能會很有用。一個人參加聚會多久了?他/她在海灘閑逛了多長時間?這可能對我們有用。

計算時間差的最直接方法是group by人員名稱,然後使用diff()命令計算時間戳字段上的差異:

df = df.sort_values(by=['name','timestamp'])
df['time_diff'] = df.groupby('name')['timestamp'].diff()

圖:計算人員活動之間的時間差,以獲取每個活動的持續時間

如果您有大量數據,並且想節省一些時間(根據數據大小的不同,速度可能會快10倍左右),則可以跳過groupby,在對數據進行排序之後做diff,然後刪除每個不相關的人的第一行。

df = df.sort_values(by=['name','timestamp'])
df['time_diff'] = df['timestamp'].diff()
df.loc[df.name != df.name.shift(), 'time_diff'] = None

其中.shift命令將所有列向下移動一格,因此我們可以通過執行以下操作查看此列在哪一行上更改:

df.name!= df.name.shift()。

其中.loc是為特定索引設置列的值。

要將time_diff更改為以秒為單位:

df['time_diff'] = df.time_diff.dt.total_seconds()

要獲得每行的持續時間:

df[‘row_duration’] = df.time_diff.shift(-1)

圖:每行持續時間

4.Cumcount and Cumsum

這是兩個非常酷的Ufunc,可以為您提供許多幫助。 Cumcount創建一個累積計數。例如,我們可以通過按人員名稱分組然後對每個人員的第二項活動應用cumcount。這將僅按活動順序對活動進行計數。然後我們可以對每個人的第二項活動僅僅進行== 1(或通過== 2)操作即可將索引應用於原始排序的DataFrame上。

df = df.sort_values(by=['name','timestamp'])
df2 = df[df.groupby(‘name’).cumcount()==1]

圖:每個人的第二項活動
df = df.sort_values(by=[‘name’,’timestamp’])
df2 = df[df.groupby(‘name’).cumcount()==2]

圖:每個人的第三項活動

Cumsum隻是數字單元格的累積匯總。例如,您可以將人員在每個活動中花費的錢添加為一個附加單元格,然後使用以下方法匯總人員在一天中的每個時間所花費的錢:

df = df.sort_values(by=[‘name’,’timestamp’])
df['money_spent_so_far'] = df.groupby(‘name’)['money_spent'].cumsum()

圖:到目前為止花的錢

5. groupby,max,min用於測量活動的持續時間

在第3節中,我們想知道每個人在每個活動中花費了多少時間。但是我們忽略了有時我們會得到多個關於活動的記錄,實際上是同一活動的繼續。因此,要獲得實際的活動持續時間,我們應該測量連續活動從第一次出現到最後一次的時間。為此,我們需要標記活動的更改,並用活動編號標記每一行。我們將使用.shift命令和.cumsum。新的活動是在活動發生變化時或者人名變了。

df['activity_change'] = (df.activity!=df.activity.shift()) | (df.name!=df.name.shift())

然後,我們將通過按用戶分組並應用強大的.cumsum來計算每行的活動編號。:

df['activity_num'] = df.groupby('name')['activity_change'].cumsum()

圖:為在行之間繼續的活動添加活動編號

現在,我們可以按照每個名稱和活動編號進行分組,並計算每行活動持續時間的總和,如下:

activity_duration = df.groupby(['name','activity_num','activity'])['activity_duration'].sum()

圖:活動時間

這將以某種timedelta類型返回活動持續時間。您可以使用.dt.total_seconds以秒為單位獲取會話活動持續時間:

activity_duration = activity_duration.dt.total_seconds()

然後,您可以使用以下命令來確定每個人的最大/最小活動持續時間(或中位數或均值):

activity_duration = activity_duration.reset_index().groupby('name').max()

圖:每個用戶的最大活動持續時間

總結

這是使用夏季活動數據集的 Pandas 之旅。希望您已經學會,祝您下一個 Pandas 項目好運!

參考資料

本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/4591.html,未經允許,請勿轉載。