如何使用熊猫将共享数据的CSV多行合并为一行?

时间:2019-06-08 17:57:36

标签: python excel pandas csv

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

第一行包括ASCAP在该歌曲中所占的百分比。 此后的行包含一个字符代码(ROLE_TYPE),该字符代码指示该行是否包含该歌曲的作者或表演者。 每行的第一列包含歌曲标题。

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

我想做的就是将这些数据从每首歌曲3行以上转换为每首歌曲1行包含所有相关数据。

所以代替:

标题,ROLE_TYPE,名称,股份,注释

我想将数据更改为:

标题,作者,表演者,股份,注释

以下是数据示例:

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出版,100,     PEOPLE KNO,SMITH ANTONIO RENARD,SMITH SHOW出版,100,     反馈,SMITH ANONIO RENARD,SMITH SHOW出版,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文件中产生一行,并包含与每首歌曲相关的所有数据?

1 个答案:

答案 0 :(得分:0)

我建议:

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

将自动对要合并的数据帧中具有相同名称的列(在这种情况下为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)