簡體   English   中英

Pandas groupby和transform基於多列

[英]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 個選項:

  1. 聚合並重新索引或連接回原始形狀
  2. 預先計算 boolean 數組並對其進行.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM