让我用这个简单的 df 作为例子。
df = pd.DataFrame([[1,1,10],[1,1,30],[1,2,40],[2,3,50],[2,3,150],[2,4,100]],columns=["col_grp","col1","col2"])
col_grp col1 col2
0 1 1 10
1 1 1 30
2 1 2 40
3 2 3 50
4 2 3 150
5 2 4 100
我希望按“col_grp”分组并将所有其他列聚合为单个值。例如,
grp['col1'].apply(lambda x: x.sum())
。
但是我希望计算一个复杂的函数,而不是简单的“sum”函数 f(x)=sum(x),该函数不仅将“col1”的 pd.Series 作为输入,而且还需要分组值,即,f(x,y)。在此示例中,对于“col_grp”值 = 1 的组,y 输入为 1。x 输入与往常一样是“col1”系列 [1,1,2]。假设 f(x,y) 可以编码,但其逻辑对于其他解决方法来说有点复杂,我仍然可以使用 grp.apply(f) 吗?如果是的话语法应该怎么写。预先感谢您。
我刚刚发现可以应用类似 f(x1,x2) 的函数,其中 x1 是“col1”系列,x2 是分组后的“col2”系列。 f(x1,x2) 返回单个值,该值是每个组的统计量。例如,
grp[['col1','col2']].apply(lambda x: x['col1'].sum() + x['col2'].median())
所以这可能是解决我的问题的有效方法。只需将分组列包含到 x 输入中即可。喜欢,
grp[['col_grp','col1','col2']].apply(lambda x: x['col_grp'].mean() + x['col1'].sum() + x['col2'].median())
我可以按照我喜欢的方式自定义 f(x)。我想我回答了我自己的问题。欢迎进一步讨论:)
使用
grp
创建组 (.groupby
) 并使用 transform
创建计算列
import pandas as pd
df = pd.DataFrame([[1,1,10],[1,1,30],[1,2,40],[2,3,50],[2,3,150],[2,4,100]],columns=["col_grp","col1","col2"])
grp = df.groupby('col_grp')
df['new_col'] = grp['col1'].transform('sum') + grp['col2'].transform('median')
df
Out[1]:
col_grp col1 col2 new_col
0 1 1 10 34
1 1 1 30 34
2 1 2 40 34
3 2 3 50 110
4 2 3 150 110
5 2 4 100 110
要使其成为您想要自定义的自己的函数,您不必使用
apply
,具体取决于您想要执行的操作。
import pandas as pd
df = pd.DataFrame([[1,1,10],[1,1,30],[1,2,40],[2,3,50],[2,3,150],[2,4,100]],columns=["col_grp","col1","col2"])
def f(dataframe, col1, col2):
grp = dataframe.groupby('col_grp')
return grp[col1].transform('sum') + grp[col2].transform('median')
df['new_col'] = f(df, 'col1', 'col2')
df
Out[2]:
col_grp col1 col2 new_col
0 1 1 10 34
1 1 1 30 34
2 1 2 40 34
3 2 3 50 110
4 2 3 150 110
5 2 4 100 110
从索引创建一个列:
df['col_group_copy'] = df.index
现在您可以按索引分组,并在函数中使用副本