[英]Enumerate each row for each group in a DataFrame
在pandas中,如何添加一個基於給定分組枚舉行的新列?
例如,假設以下DataFrame:
import pandas as pd
import numpy as np
a_list = ['A', 'B', 'C', 'A', 'A', 'C', 'B', 'B', 'A', 'C']
df = pd.DataFrame({'col_a': a_list, 'col_b': range(10)})
df
col_a col_b
0 A 0
1 B 1
2 C 2
3 A 3
4 A 4
5 C 5
6 B 6
7 B 7
8 A 8
9 C 9
我想補充一個col_c
,讓我根據的一組的“組”的第N行col_a
和排序col_b
。
期望的輸出:
col_a col_b col_c
0 A 0 1
3 A 3 2
4 A 4 3
8 A 8 4
1 B 1 1
6 B 6 2
7 B 7 3
2 C 2 1
5 C 5 2
9 C 9 3
我很難去col_c
。 您可以使用.sort_index(by=['col_a', 'col_b'])
進行正確的分組和排序,現在需要訪問新列並標記每一行。
有暨計數 ,正是這種情況:
df['col_c'] = g.cumcount()
正如它在文檔中所說:
將每個組中的每個項目編號從0到該組的長度 - 1。
原始答案(在cumcount定義之前)。
您可以創建一個輔助函數來執行此操作:
def add_col_c(x):
x['col_c'] = np.arange(len(x))
return x
首先按列col_a排序:
In [11]: df.sort('col_a', inplace=True)
然后在每個組中應用此功能:
In [12]: g = df.groupby('col_a', as_index=False)
In [13]: g.apply(add_col_c)
Out[13]:
col_a col_b col_c
3 A 3 0
8 A 8 1
0 A 0 2
4 A 4 3
6 B 6 0
1 B 1 1
7 B 7 2
9 C 9 0
2 C 2 1
5 C 5 2
為了獲得1,2,...
你可以使用np.arange(1, len(x) + 1)
。
給出的答案都涉及為每個組調用python函數,如果你有很多組,矢量化方法應該更快(我沒有檢查)。
這是我純粹的numpy建議:
In [5]: df.sort(['col_a', 'col_b'], inplace=True, ascending=(False, False))
In [6]: sizes = df.groupby('col_a', sort=False).size().values
In [7]: df['col_c'] = np.arange(sizes.sum()) - np.repeat(sizes.cumsum() - sizes, sizes)
In [8]: print df
col_a col_b col_c
9 C 9 0
5 C 5 1
2 C 2 2
7 B 7 0
6 B 6 1
1 B 1 2
8 A 8 0
4 A 4 1
3 A 3 2
0 A 0 3
您可以定義自己的函數來處理:
In [58]: def func(x):
....: x['col_c'] = x['col_a'].argsort() + 1
....: return x
....:
In [59]: df.groupby('col_a').apply(func)
Out[59]:
col_a col_b col_c
0 A 0 1
3 A 3 2
4 A 4 3
8 A 8 4
1 B 1 1
6 B 6 2
7 B 7 3
2 C 2 1
5 C 5 2
9 C 9 3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.