基于Pandas数据框中其他列的值计算列值的方法。

7

我想要统计每个唯一的 xy 组合中每个类别的风暴数量。例如,我的数据框如下:

x   y  year  Category
1   1  1988     3
2   1  1977     1
2   1  1999     2
3   2  1990     4

我想创建一个类似于这样的数据框:

x   y   Category 1   Category 2   Category 3  Category 4
1   1        0           0            1           0
2   1        1           1            0           0
3   2        0           0            0           1

我尝试了各种.groupby().count()的组合,但是仍然没有得到期望的结果。我能得到的最接近的结果是:

df[['x','y','Category']].groupby(['Category']).count()

然而,该结果计算了所有的 xy,而不是唯一的一对:

Cat       x           y     
1       3773         3773
2       1230         1230
3       604          604
4       266          266
5       50           50
NA      27620        27620
TS      16884        16884

有人知道如何在数据框中基于另外两列的唯一性对一列进行计数操作吗?

4个回答

2
pivot_table听起来就像是你想要的。一个小技巧是添加一列1来用于计数。这允许pivot_table为特定的x-yCategory组合的每个出现次数添加1。您将在pivot_table中将此新列设置为您的value参数,并将aggfunc参数设置为np.sum。您还可能希望将fill_value设置为0
df['count'] = 1
result = df.pivot_table(
    index=['x', 'y'], columns='Category', values='count',
    fill_value=0, aggfunc=np.sum
)

result:

Category  1  2  3  4
x y                 
1 1       0  0  1  0
2 1       1  1  0  0
3 2       0  0  0  1

如果您希望将xy保留为列,并将其他列名更改为Category X,您可以重命名列并使用reset_index:Original Answer。
result.columns = [f'Category {x}' for x in result.columns]
result = a.reset_index()

1
那个计数列和聚合函数非常聪明。 - Mohit Motwani
1
谢谢,我其实还希望有人能指出更简洁的方法! - busybear
很干净。但是请解释一下为什么使用count = 1。因为其他读者可能会感到困惑。 - Mohit Motwani

1
你可以先使用 groupby
df_new = df.groupby(['x', 'y', 'Category']).count()
df_new
                  year  count
x   y   Category        
1   1      3       1    1
2   1      1       1    1
           2       1    1
3   2      4       1    1

然后 pivot_table
df_new = df_new.pivot_table(index=['x', 'y'], columns='Category', values='count', fill_value=0)
df_new
Category    1   2   3   4
x   y               
1   1       0   0   1   0
2   1       1   1   0   0
3   2       0   0   0   1

1

您可以在使用set_index设置索引后,使用pd.get_dummies,然后使用sumlevel参数来折叠行:

pd.get_dummies(df.set_index(['x','y'])['Category'].astype(str),
               prefix='Category ', 
               prefix_sep='')\
  .sum(level=[0,1])\
  .reset_index()

输出:

   x  y  Category 1  Category 2  Category 3  Category 4
0  1  1           0           0           1           0
1  2  1           1           1           0           0
2  3  2           0           0           0           1

0

或者使用groupby两次,加上很多额外的操作,例如使用get_dummiesapply等...

像这样:

>>> df.join(df.groupby(['x','y'])['Category']
           .apply(lambda x: x.astype(str).str.get_dummies().add_prefix('Category ')))
           .groupby(['x','y']).sum().fillna(0).drop(['year','Category'],1).reset_index()
   x  y  Category 1  Category 2  Category 3  Category 4
0  1  1         0.0         0.0         1.0         0.0
1  2  1         1.0         1.0         0.0         0.0
2  3  2         0.0         0.0         0.0         1.0
>>> 

1
@MohitMotwani 做完了。 - U13-Forward

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接