Pandas的df groupby和apply

4
假设有以下数据框:
df = pd.DataFrame(
    {
    'col 1': ['A', 'A', 'B', 'B', 'C'],
    'col 2': ['c2', 'd2', 'e2', 'f2', 'g2'],
    'col 3': ['c3', 'd3', 'e3', 'f3', 'g3'],
    'col 4': ['c4', 'd4', 'e4', 'f4', 'g4'],
    }
    )

期望输出为:
col 1  col 2  col 3
A      c2;d2  c3;d3
B      e2;f2  e3;f3
C      g2     g3

我已经成功地以以下方式完成了这个任务:
df = df.groupby('col 1').transform( lambda x: ';'.join(x)).drop_duplicates()

问题是这种方法没有保留我真正需要的第一列。我无法让apply起作用。我尝试了像这样的方法,但在groupby之后好像不起作用。
apply(lambda x: '*'.join(x.dropna().values.tolist()), axis=1)

1
你正在将一个带有“col 3”重复两次作为键的dict传递给你的DF - DF只会看到该键的最后一次出现... - Jon Clements
1
这是一个不错的修复,我没有想到,但是jezrael发布的解决方案简单并且满足我的需求。谢谢! - Mike Vlad
2个回答

5

我认为您可以使用功能DataFrameGroupBy.agg在列表中指定groupby后的列,无需使用lambda函数

df1 = df.groupby('col 1')['col 2','col 3'].agg(';'.join).reset_index()
#alternative
#df1 = df.groupby('col 1', as_index=False)['col 2','col 3'].agg(';'.join)
print (df1)
  col 1  col 2  col 3
0     A  c2;d2  c3;d3
1     B  e2;f2  e3;f3
2     C     g2     g3

如果想要同时移除缺失值:
df = pd.DataFrame(
    {
    'col 1': ['A', 'A', 'B', 'B', 'C'],
    'col 2': [np.nan, 'd2', 'e2', 'f2', 'g2'],
    'col 3': ['c3', 'd3', 'e3', 'f3', 'g3'],
    'col 4': ['c4', 'd4', 'e4', 'f4', 'g4'],
    }
    )
print (df)
  col 1 col 2 col 3 col 4
0     A   NaN    c3    c4
1     A    d2    d3    d4
2     B    e2    e3    e4
3     B    f2    f3    f4
4     C    g2    g3    g4

df1 = (df.groupby('col 1', as_index=False)['col 2','col 3']
         .agg(lambda x: ';'.join(x.dropna())))
print (df1)
  col 1  col 2  col 3
0     A     d2  c3;d3
1     B  e2;f2  e3;f3
2     C     g2     g3

4

应用于 col 1 的分组(将索引指定为 false,以便它保持为列)。 对每个组应用 lambda 函数,其中将每个组的值用分号连接起来。然后按所需列顺序(例如 col 1-3)对结果进行排序。

df = pd.DataFrame(
    {'col 1': ['A', 'A', 'B', 'B', 'C'],
     'col 2': ['c2', 'd2', 'e2', 'f2', 'g2'],
     'col 3': ['c3', 'd3', 'e3', 'f3', 'g3'],
     'col 4': ['c4', 'd4', 'e4', 'f4', 'g4']})

>>> df.groupby('col 1', as_index=False).agg(
        {'col 2': lambda x: ';'.join(x),
         'col 3': lambda x: ';'.join(x)})[['col 1', 'col 2', 'col 3']]
  col 1  col 2  col 3
0     A  c2;d2  c3;d3
1     B  e2;f2  e3;f3
2     C     g2     g3

我认为它解决了我的问题,但是Jezrael发布的解决方案似乎更简单。不知道哪个执行速度更快。谢谢! - Mike Vlad

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