获取多列分组的结果并直接在我的数据框中计数

时间:2019-01-29 19:10:25

标签: python pandas pandas-groupby

我有一个数据框(下面的玩具示例来自另一个帖子),您可以使用以下代码生成该数据框;我想按列'col1'和'col2'进行分组,并计算每个组中的出现次数,如下例所示:How to count number of rows per group (and other statistics) in pandas group by?

但是要像本例中那样将结果直接包括到我的数据框中(其中只有一列要分组):Pandas, group by count and add count to original dataframe?

我尝试过:

df['count'] = df.groupby(['col1','col2']).transform('count')

并且:

df['count'] = df.groupby(['col1','col2'])[['col1','col2']].transform('count')

但是我两次都遇到相同的错误:

ValueError: Length of passed values is 10, index implies 0 

有什么想法可以解决这个问题,而不必将结果合并到我的初始数据帧中吗?在R dplyr中,使用groupbymutaten()非常容易。...

玩具示例:

  col1 col2  col3  col4  col5  col6
0    A    B  0.20 -0.61 -0.49  1.49
1    A    B -1.53 -1.01 -0.39  1.82
2    A    B -0.44  0.27  0.72  0.11
3    A    B  0.28 -1.32  0.38  0.18
4    C    D  0.12  0.59  0.81  0.66
5    C    D -0.13 -1.65 -1.64  0.50
6    C    D -1.42 -0.11 -0.18 -0.44
7    E    F -0.00  1.42 -0.26  1.17
8    E    F  0.91 -0.47  1.35 -0.34
9    G    H  1.48 -0.63 -1.14  0.17

生成玩具数据框的代码:

import numpy as np
import pandas as pd 

keys = np.array([
   ['A', 'B'],
   ['A', 'B'],
     ['A', 'B'],
  ['A', 'B'],
     ['C', 'D'],
   ['C', 'D'],
   ['C', 'D'],
   ['E', 'F'],
   ['E', 'F'],
   ['G', 'H'] 
   ])

df = pd.DataFrame(
np.hstack([keys,np.random.randn(10,4).round(2)]), 
columns = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6']
)

df[['col3', 'col4', 'col5', 'col6']] = df[['col3', 'col4', 
'col5','col6']].astype(float)

2 个答案:

答案 0 :(得分:1)

编辑

在@Alollz注释之后,可以将代码简化为一行,而无需串联: df['count'] = df.groupby(['col1', 'col2'])['col1'].transform('size')


修改前的答案

解决方法是在应用分组依据之前先创建一个concatenated列。

之后,您可以在size方法中使用transform函数。

也许不是最优雅的,但它可以工作。

代码

# make a concatenated column 
df['concat'] = df.col1 + df.col2

# perform the transformation asked
df['count'] = df.groupby(['concat'])['concat'].transform('size')

# drop the concat column
df.drop('concat', axis=1, inplace=True)


    col1col2col3    col4    col5    col6    count
0   A   B   -0.62   0.09    0.92    1.45    4
1   A   B   1.49    0.31    -0.40   -0.99   4
2   A   B   -1.30   1.01    -0.31   -0.32   4
3   A   B   -0.05   0.32    -1.45   -0.54   4
4   C   D   -1.30   1.26    1.80    0.50    3
5   C   D   0.75    0.13    0.49    -2.37   3
6   C   D   1.05    -0.96   -0.44   -1.00   3
7   E   F   0.31    -0.93   -1.78   -1.49   2
8   E   F   -0.23   0.30    0.77    1.46    2
9   G   H   -0.67   0.88    -0.26   -1.09   1

希望这会有所帮助。

答案 1 :(得分:1)

如果将groupby()的结果进行stack(),则结果将适合DataFrame行的长度。然后,reset_index()将使其适合先前的DataFrame。

df['count'] = df.groupby(['col1', 'col2']).count().stack().reset_index()[0]

会给你...

import numpy as np
import pandas as pd 

keys = np.array([
   ['A', 'B'],
   ['A', 'B'],
     ['A', 'B'],
  ['A', 'B'],
     ['C', 'D'],
   ['C', 'D'],
   ['C', 'D'],
   ['E', 'F'],
   ['E', 'F'],
   ['G', 'H'] 
   ])

df = pd.DataFrame(
np.hstack([keys,np.random.randn(10,4).round(2)]), 
columns = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6']
)

df[['col3', 'col4', 'col5', 'col6']] = df[['col3', 'col4', 
'col5','col6']].astype(float)

df_count = df.groupby(['col1', 'col2']).count()
print(df_count)
#            col3  col4  col5  col6
# col1 col2                        
# A    B        4     4     4     4
# C    D        3     3     3     3
# E    F        2     2     2     2
# G    H        1     1     1     1
stacked_count = df_count.stack()
print(stacked_count)
# col1  col2      
# A     B     col3    4
#             col4    4
#             col5    4
#             col6    4
# C     D     col3    3
#             col4    3
#             col5    3
#             col6    3
# E     F     col3    2
#             col4    2
#             col5    2
#             col6    2
# G     H     col3    1
#             col4    1
#             col5    1
#             col6    1
# dtype: int64

ndf = stacked_count.reset_index()[0]
print(ndf)
# 0     4
# 1     4
# 2     4
# 3     4
# 4     3
# 5     3
# 6     3
# 7     3
# 8     2
# 9     2
# 10    2
# 11    2
# 12    1
# 13    1
# 14    1
# 15    1
# Name: 0, dtype: int64

df['count'] = ndf
print(df)
#   col1 col2  col3  col4  col5  col6  count
# 0    A    B -0.81 -1.39  0.07  0.71      4
# 1    A    B -1.37  1.72 -2.04  0.83      4
# 2    A    B -1.81 -0.53 -1.27 -0.83      4
# 3    A    B -1.05 -0.06 -1.78  0.81      4
# 4    C    D -1.40  0.36  0.94  1.90      3
# 5    C    D  0.65  0.49 -1.78  0.10      3
# 6    C    D -0.57 -0.08  1.11 -0.73      3
# 7    E    F  0.37  0.99 -1.62 -1.26      3
# 8    E    F  0.09 -0.03  1.27  0.80      2
# 9    G    H  0.26  0.71  0.05  0.48      2