首页 > 解决方案 > 在Python中按组将多行加入逗号分隔的字符串

问题描述

我有一个类似于下面的数据框:

ID 类型 日期
01 佩尔 美联储 2021-06-01
01 SCH LOC 2021-06-01
02 SCH LOC 2021-06-04
03 授予 STA 2021-06-02
03 佩尔 美联储 2021-06-15
03 SCH LOC 2021-07-01

我想将其转换为以下数据框:

ID 类型 日期
01 佩尔,SCH 美联储,LOC 2021-06-01, 2021-06-01
02 SCH LOC 2021-06-04
03 格兰特,佩尔,SCH STA,美联储,LOC 2021-06-02, 2021-06-15, 2021-07-01

在这种情况下,我按 ID 分组。但是,可能有多个分组列(例如,ID 和 TERM 而不仅仅是 ID)。我将分组列存储在名为“keys”的列表变量中。

每个分组可能有不同数量的项目,但非分组列对于每个组都有相同数量的项目(对于上面数据框中的 ID=01,其他列都将有 2 行)。

所有列都作为字符串从 csv 文件中读取(在 pd.read_csv 上使用 dtype=str),以防止从原始值更改任何值(我不希望重新解释数字或更改日期格式)。

我已经尝试了以下内容,但这些似乎都不起作用。

import pandas as pd 
keys = ['ID']
df = pd.DataFrame({
    'ID' : ['01','01','02','03','03','03'],
    'Award' : ['PELL','SCH','SCH','GRANT','PELL','SCH'],
    'Type' : ['FED','LOC','LOC','STA','FED','LOC'],
    'Date' : ['2021-06-01','2021-06-01','2021-06-04','2021-06-02','2021-06-15','2021-07-01'],
})
dfb = df.groupby(keys).apply(', '.join) # This results in the column names being joined together, not the column values
dfc = df.groupby(keys).agg(list) # This results in lists instead of concatenated strings

输出:

dfb
ID
01    ID, Award, Type, Date
02    ID, Award, Type, Date
03    ID, Award, Type, Date
dtype: object

dfc
                 Award             Type                                  Date
ID                                                                           
01         [PELL, SCH]       [FED, LOC]              [2021-06-01, 2021-06-01]
02               [SCH]            [LOC]                          [2021-06-04]
03  [GRANT, PELL, SCH]  [STA, FED, LOC]  [2021-06-02, 2021-06-15, 2021-07-01]

我想要一个关于去哪里的指针。当然,我仍然在 Python 的这方面苦苦挣扎!

标签: pythonpandasstringdataframeconcatenation

解决方案


尝试这个 -

  1. 创建一个字典,其中包含除ID键和lambda x: list(x)函数之外的所有必需列。
  2. 使用groupbywithagg在每列上应用独立函数。
  3. 如果要将 转换list为连接字符串,则只需将 lambda 函数更改为lambda x: ', '.join(list(x))

如果您有兴趣,可以在我的博客上找到有关如何使用复杂 groupby 和聚合的更多详细信息。

g = {i:lambda x: ', '.join(list(x)) for i in df.columns[1:]}

output = df.groupby(['ID']).agg(g).reset_index()
print(output)
   ID             Award           Type                                Date
0  01         PELL, SCH       FED, LOC              2021-06-01, 2021-06-01
1  02               SCH            LOC                          2021-06-04
2  03  GRANT, PELL, SCH  STA, FED, LOC  2021-06-02, 2021-06-15, 2021-07-01

编辑:

如果目标是只得到一个逗号分隔的字符串,那么@Henry Ecker 建议的更短的方法是 ..

output = df.groupby(['ID'], as_index=False).agg(', '.join)

.. 仅使用方法本身的聚合。


推荐阅读