pandas groupby 按总和聚合特定列,按最常见值聚合其他列

Posted

技术标签:

【中文标题】pandas groupby 按总和聚合特定列,按最常见值聚合其他列【英文标题】:pandas groupby aggregate specific columns by sum and other columns by most common value 【发布时间】:2020-07-03 11:32:46 【问题描述】:

我有一个看起来像这样的数据框:

road    dirn    length  lane
1        L         0     2
1        L       0.6     2
1        L       1.2     1
1        L       0.8     2
2        R       1.5     3
2        R       0.4     2
2        R         9     3

我需要聚合这个数据框,我将在其中按“road”和“dirn”列进行分组,并在“length”列上求和,并从“lanes”列中获取最常见的值。生成的数据框应如下所示:

road    dirn    length  lanes
1        L       2.6     2
1        L      10.9     3

我可以使用 groupby、agg 和 sum 轻松地进行 groupby 和 sum。我已经看到可以使用 value_counts 获得最常见的值,但我不确定如何将 sum 和 value_counts 结合起来。实际的数据框非常大,我可能需要将总和和值计数应用于多列。

谁能帮我理解: i)如何分组并获取“长度”的总和以及“车道”的最常见值 ii)如何将其扩展为 groupby(多列),对多列求和),最常见的值(重命名列)

【问题讨论】:

【参考方案1】:

GroupBy.aggsum 一起使用,最常见的值使用Series.mode

df1 = (df.groupby(['road','dirn'], as_index=False)
         .agg('length':'sum','lane':lambda x: x.mode().iat[0]))

Series.value_counts类似的想法:

df1 = (df.groupby(['road','dirn'], as_index=False)
         .agg('length':'sum','lane':lambda x: x.value_counts().index[0]))

print (df1)
   road dirn  length  lane
0     1    L     2.6     2
1     2    R    10.9     3

编辑:如果有两个聚合函数的列名列表,则可以使用GroupBy.agg** 合并的字典:

sumL = ['length', 'accidents']
modeL = ['lane']

func = lambda x: x.value_counts().index[0]

d = **dict.fromkeys(sumL, 'sum'), **dict.fromkeys(modeL, func)
print (d)

df1 = df.groupby(['road','dirn'], as_index=False).agg(d)

【讨论】:

不要认为你需要iat 模式:df.groupby(["road", "dirn"], as_index=False).agg( "length": "sum", "lane": lambda x: x.mode() ) 似乎工作正常 @sammywemmy - 是的,iat 是多个最常见的值,然后它返回第一个值。 @sammywemmy - 可以测试是否先将2 更改为1,如果没有iat 则失败ValueError: Function does not reduce @jezrael 他们都工作!非常感谢你。你能告诉我如何为 sum 和 mode/value_counts 函数传递一个 olumns 列表而不是单个列吗?我的数据框有 70 多列。 @jezrael 是的,没错。例如,我有以下列来求和 - 长度、事故、十字路口和模式 - 车道、路肩、道路照明等。我有这些列多年的数据,因此大约 70 列。【参考方案2】:

下面的代码将给出length 列的总和,并提供lane 列的mode

df.groupby(['road','dirn']).agg('length':[np.sum],'lane':[pd.Series.mode])

下面的代码将对length 列求和并提供lane 列的最大值

df.groupby(['road','dirn']).agg('length':[np.sum],'lane':[np.max]

【讨论】:

感谢您的回复。解决方案有效。但是我现在可以看到这适用于数字数据。不幸的是,我也有一些描述性的字符串数据。对于这种情况,value_counts 会按预期工作。

以上是关于pandas groupby 按总和聚合特定列,按最常见值聚合其他列的主要内容,如果未能解决你的问题,请参考以下文章

Pandas groupby 将特定函数聚合/应用到特定列(np.sum,sum)

Pandas 数据透视表:按特定字符串的计数聚合函数

Pandas groupby 和聚合输出应包括所有原始列(包括未聚合的列)

最近 n_days 使用 groupby 在特定列上的累积总和

Pandas 按 groupby 求和,但不包括某些列

Pandas - 按函数和总和列分组以提取其他列总和为 0 的行