【问题标题】:How do I combine multiple rows of a CSV that share data into one row using Pandas?如何使用 Pandas 将共享数据的多行 CSV 合并为一行?
【发布时间】:2019-06-08 17:57:36
【问题描述】:

我已经下载了ASCAP database,给了我一个对于 Excel 来说太大而无法处理的 CSV。我可以对 CSV 进行分块以打开其中的一部分,问题是数据在其默认格式中并不是很有帮助。每首歌曲的标题都有 3+ 行与之关联:

第一行包括 ASCAP 在该歌曲中的份额百分比。 之后的行包括一个字符代码 (ROLE_TYPE),指示该行是否包含该歌曲的作者或表演者。 每行的第一列包含一个歌曲名称。

这种结构使数据混乱,因为在列出 % 份额的行中,NAME 列中有空白单元格,因为该行没有与之关联的 Writer/Performer。

我想做的是将此数据从每首歌曲超过 3 行转换为每首歌曲 1 行包含所有相关数据。

所以而不是:

TITLE、ROLE_TYPE、NAME、SHARES、NOTE

我想把数据改成:

头衔、作者、表演者、股份、备注

以下是数据示例:

TITLE,ROLE_TYPE,NAME,SHARES,NOTE
SCORE MORE,ASCAP,Total Current ASCAP Share,100,
SCORE MORE,W,SMITH ANTONIO RENARD,,
SCORE MORE,P,SMITH SHOW PUBLISHING,,
PEOPLE KNO,ASCAP,Total Current ASCAP Share,100,
PEOPLE KNO,W,SMITH ANTONIO RENARD,,
PEOPLE KNO,P,SMITH SHOW PUBLISHING,,
FEEDBACK,ASCAP,Total Current ASCAP Share,100,
FEEDBACK,W,SMITH ANTONIO RENARD,,

我希望数据看起来像: 标题,作家,表演者,股份,注 得分更多,SMITH ANTONIO RENARD,SMITH SHOW PUBLISHING,100, PEOPLE KNO,SMITH ANTONIO RENARD,SMITH SHOW PUBLISHING,100, 反馈,SMITH ANONIO RENARD,SMITH SHOW Publishing,100,

我正在使用 python/pandas 来尝试处理数据。我可以使用 groupby('TITLE') 对具有匹配标题的行进行分组。

import pandas as pd

data = pd.read_csv("COMMA_ASCAP_TEXT.txt", low_memory=False)

title_grouped = data.groupby('TITLE')

for TITLE,group in title_grouped:
  print(TITLE)
  print(group)

我能够对每首歌曲进行分组('TITLE'),我得到的输出似乎接近我想要的:

SCORE MORE
   TITLE          ROLE_TYPE  NAME                        SHARES    NOTE
0  SCORE MORE     ASCAP      Total Current ASCAP Share   100.0     NaN
1  SCORE MORE         W      SMITH ANTONIO RENARD        NaN       NaN
2  SCORE MORE         P      SMITH SHOW PUBLISHING       NaN       NaN 

我需要做些什么来获取这个组并在 CSV 文件中生成一行,其中包含与每首歌曲相关的所有数据?

【问题讨论】:

  • 您的预期结果是什么?
  • 关于字段位置和转换逻辑的问题不明确。提供一些示例输出。从输入数据到输出数据的详细映射。

标签: python excel pandas csv


【解决方案1】:

我会推荐:

  • 按 ROLE_TYPE 分解数据
  • 准备合并数据(重命名列并删除不必要的列)
  • 将所有内容合并回一个 DataFrame

合并将自动对正在合并的DataFrames中具有相同名称的列进行合并(本例中为TITLE)。

似乎工作得很好:)

data = pd.read_csv("data2.csv", sep=",")

# Create 3 individual DataFrames for different roles
data_ascap = data[data["ROLE_TYPE"] == "ASCAP"].copy()
data_writer = data[data["ROLE_TYPE"] == "W"].copy()
data_performer = data[data["ROLE_TYPE"] == "P"].copy()

# Remove unnecessary columns for ASCAP role
data_ascap.drop(["ROLE_TYPE", "NAME"], axis=1, inplace=True)

# Rename columns and remove unnecesary columns for WRITER role
data_writer.rename(index=str, columns={"NAME": "WRITER"}, inplace=True)
data_writer.drop(["ROLE_TYPE", "SHARES", "NOTE"], axis=1, inplace=True)

# Rename columns and remove unnecesary columns for PERFORMER role
data_performer.rename(index=str, columns={"NAME": "PERFORMER"}, inplace=True)
data_performer.drop(["ROLE_TYPE", "SHARES", "NOTE"], axis=1, inplace=True)

# Merge all together
result = data_ascap.merge(data_writer, how="left")
result = result.merge(data_performer, how="left")

# Print result
print(result)

【讨论】:

  • 工作就像一个魅力!我正在考虑遍历分组数据和各种疯狂的废话,但是您的解决方案干净而简单。非常感谢!最后一个问题,这与我提出的问题并不完全相关,但是这个解决方案如何处理大量数据? ASCAP 数据库中有数百万行,我要到今晚晚些时候才能运行完整的数据集,我想知道从中期待什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
相关资源
最近更新 更多