[英]Pandas groupby and transform based on multiple columns
我見過很多類似的問題,但似乎沒有一個適合我的情況。 我很確定這只是一個 groupby 轉換,但我不斷收到KeyError
以及axis
問題。 我正在嘗試對filename
進行分組並檢查pred != gt
的計數。
例如,索引 2 是f1.wav
所以 1 的唯一一個,而f2.wav
所以 3 是索引 (13,14,18)。
df = pd.DataFrame([{'pred': 0, 'gt': 0, 'filename': 'f1.wav'}, {'pred': 0, 'gt': 0, 'filename': 'f1.wav'}, {'pred': 2, 'gt': 0, 'filename': 'f1.wav'}, {'pred': 0, 'gt': 0, 'filename': 'f1.wav'}, {'pred': 0, 'gt': 0, 'filename': 'f1.wav'}, {'pred': 0, 'gt': 0, 'filename': 'f1.wav'}, {'pred': 0, 'gt': 0, 'filename': 'f1.wav'}, {'pred': 0, 'gt': 0, 'filename': 'f1.wav'}, {'pred': 0, 'gt': 0, 'filename': 'f1.wav'}, {'pred': 0, 'gt': 0, 'filename': 'f1.wav'}, {'pred': 0, 'gt': 0, 'filename': 'f2.wav'}, {'pred': 0, 'gt': 0, 'filename': 'f2.wav'}, {'pred': 2, 'gt': 2, 'filename': 'f2.wav'}, {'pred': 0, 'gt': 2, 'filename': 'f2.wav'}, {'pred': 0, 'gt': 2, 'filename': 'f2.wav'}, {'pred': 0, 'gt': 0, 'filename': 'f2.wav'}, {'pred': 0, 'gt': 0, 'filename': 'f2.wav'}, {'pred': 2, 'gt': 2, 'filename': 'f2.wav'}, {'pred': 0, 'gt': 2, 'filename': 'f2.wav'}, {'pred': 2, 'gt': 0, 'filename': 'f2.wav'}])
pred gt filename
0 0 0 f1.wav
1 0 0 f1.wav
2 2 0 f1.wav
3 0 0 f1.wav
4 0 0 f1.wav
5 0 0 f1.wav
6 0 0 f1.wav
7 0 0 f1.wav
8 0 0 f1.wav
9 0 0 f1.wav
10 0 0 f2.wav
預期 output
pred gt filename counts
0 0 0 f1.wav 1
1 0 0 f1.wav 1
2 2 0 f1.wav 1
3 0 0 f1.wav 1
4 0 0 f1.wav 1
5 0 0 f1.wav 1
6 0 0 f1.wav 1
7 0 0 f1.wav 1
8 0 0 f1.wav 1
9 0 0 f1.wav 1
10 0 0 f2.wav 3
11 0 0 f2.wav 3
12 2 2 f2.wav 3
13 0 2 f2.wav 3
14 0 2 f2.wav 3
15 0 0 f2.wav 3
16 0 0 f2.wav 3
17 2 2 f2.wav 3
18 0 2 f2.wav 3
19 2 0 f2.wav 3
我在想df.groupby('filename').transform(lambda x: x['pred'].ne(x['gt']).sum(), axis=1)
但我得到TypeError: Transform function invalid for data types
.transform
單獨對每一列進行操作,因此您將無法在轉換操作中同時訪問“pred”和“gt”。
這為您提供了 2 個選項:
.transform
方法2可能是這里最快的:
df['counts'] = (
(df['pred'] != df['gt'])
.groupby(df['filename']).transform('sum')
)
print(df)
pred gt filename counts
0 0 0 f1.wav 1
1 0 0 f1.wav 1
2 2 0 f1.wav 1
3 0 0 f1.wav 1
4 0 0 f1.wav 1
5 0 0 f1.wav 1
6 0 0 f1.wav 1
7 0 0 f1.wav 1
8 0 0 f1.wav 1
9 0 0 f1.wav 1
10 0 0 f2.wav 4
11 0 0 f2.wav 4
12 2 2 f2.wav 4
13 0 2 f2.wav 4
14 0 2 f2.wav 4
15 0 0 f2.wav 4
16 0 0 f2.wav 4
17 2 2 f2.wav 4
18 0 2 f2.wav 4
19 2 0 f2.wav 4
請注意, f2.wav
有 4 個實例,其中 'pre',= 'gt' (索引 13、14、18、19)
Considering that df
is the dataframe OP shares in the question, in order to groupby filename
and check count where pred
!=
gt
, one can use pandas.DataFrame.groupby
and pandas.DataFrame.apply
as follows
df2 = df.groupby('filename').apply(lambda x: x[x['pred'] != x['gt']])
[Out]:
pred gt filename
filename
f1.wav 2 2 0 f1.wav
f2.wav 13 0 2 f2.wav
14 0 2 f2.wav
18 0 2 f2.wav
19 2 0 f2.wav
假設要計算每個filename
的出現次數,因為在前面的操作之后, filename
既是索引級別又是列 label,這是模棱兩可的,並且考慮到 OP 希望有一個名為count
的列來計算數量對於每組中的每個項目,必須按級別pandas.core.groupby.GroupBy.cumcount
groupby
(注意:與接受的答案相反,這種方法將按順序計算)
df2['count'] = df2.groupby(level=0).cumcount() + 1 # The +1 is to make the count start at 1 instead of 0.
[Out]:
pred gt filename count
filename
f1.wav 2 2 0 f1.wav 1
f2.wav 13 0 2 f2.wav 1
14 0 2 f2.wav 2
18 0 2 f2.wav 3
19 2 0 f2.wav 4
單線將如下所示
df2['count'] = df.groupby('filename').apply(lambda x: x[x['pred'] != x['gt']]).groupby(level=0).cumcount() + 1
[Out]:
pred gt filename count
filename
f1.wav 2 2 0 f1.wav 1
f2.wav 13 0 2 f2.wav 1
14 0 2 f2.wav 2
18 0 2 f2.wav 3
19 2 0 f2.wav 4
如果不需要在單獨的列中進行計數,則在此答案中提到的第一個操作(創建df2
時)之后將df2
視為 dataframe ,那么可以簡單地使用以下內容(提供更高級的概述)
df3 = df2.groupby(level=0).count().iloc[:, 0]
[Out]:
filename
f1.wav 1
f2.wav 4
Name: pred, dtype: int64
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.