将CSV行与公共数据合并并更新计数

时间:2016-06-17 19:14:40

标签: python csv pandas join

我有一个包含如下数据的CSV:

document_id | body_mention |数

doc_01 |鲍勃| 5

doc_03 |山姆| 1

doc_04 |鲍勃| 1

其中body_mention是从文本中解析出来的名称,count是该名称出现在某个文档中的次数(document_id)。所以,Bob在doc_01中出现了5次。

但是,我希望我的CSV更新,以便Bob的出现只会更新以前的Bob条目,因此新的更新如下所示:

document_id | body_mention |数

doc_01,doc_04 |鲍勃| 6

doc_03 |山姆| 1

我有什么想法可以开始编写脚本吗?

3 个答案:

答案 0 :(得分:0)

它有点尴尬但你可以使用两个默认值,一个用于跟踪每个人的所有文档,另一个用于保存文档所有值的总和

import csv
import collections

name_sum = collections.defaultdict(int)
docs_for_name = collections.defaultdict(list)

with open("csv1.csv") as csvfile:
    csvreader = csv.reader(csvfile)
    for row in csvreader:
        name_sum[row[1]] += int(row[2])
        docs_for_name[row[1]].append(row[0])

with open("outputcsv.csv", "w", newline="") as csvfile:
    csvwriter = csv.writer(csvfile)
    for key in sorted(name_sum.keys()):
        row = [", ".join(sorted(docs_for_name[key])), key, str(name_sum[key])]
        print(row)
        csvwriter.writerow(row)

你没有发布一个真正的csv文件,就像csv文件在像excel这样的编辑器中的样子,所以我假设你的csv看起来像这样:

doc_01,Bob,5
doc_03,Sam,1
doc_04,Bob,1

这最终会输出一个csv文件,如:

"doc_01, doc_04",Bob,6
doc_03,Sam,1

enter image description here

第一个默认值name_sum只跟踪每个名称的所有值的总和,因此最终看起来像

defaultdict(<class 'int'>, {'Bob': 6, 'Sam': 1})

另一个默认用于跟踪名称的所有文档,docs_for_name最终看起来像:

defaultdict(<class 'list'>, {'Bob': ['doc_01', 'doc_04'], 'Sam': ['doc_03']})

然后,您将获得编写新csv文件中每一行所需的所有信息

答案 1 :(得分:0)

您可以使用csvpandas读取import pandas as pd; pd.read_csv()。然后您可以将数据存储在Dataframe内,如下所示:

df
Out[86]: 
  document_id body_mention  count
0      doc_01          Bob      5
1      doc_03          Sam      1
2      doc_04          Bob      1

之后,为了达到你想要的效果,你可以使用以下两行代码:

rslt = pd.concat([df.groupby('body_mention').sum(), df.groupby('body_mention').apply(lambda x: ','.join(x['document_id']))], axis=1).reset_index()
rslt.columns = ['body_mention', 'count', 'document_id']

<强>解释

In [91]: rslt = pd.concat([df.groupby('body_mention').sum(), df.groupby('body_mention').apply(lambda x: ','.join(x['document_id']))], axis=1).reset_index()

In [92]: rslt
Out[92]: 
  body_mention  count              0
0          Bob      6  doc_01,doc_04
1          Sam      1         doc_03

In [93]: rslt.columns = ['body_mention', 'count', 'document_id']

In [94]: rslt
Out[94]: 
  body_mention  count    document_id
0          Bob      6  doc_01,doc_04
1          Sam      1         doc_03

最后,您可以使用rslt.to_csv('rslt.csv')将结果数据框保存到csv

ps,如果您希望输出列遵循确切的顺序,请使用以下内容:

rslt = rslt[['document_id', 'body_mention', 'count']]

rslt
Out[99]: 
     document_id body_mention  count
0  doc_01,doc_04          Bob      6
1         doc_03          Sam      1

答案 2 :(得分:0)

试试这个:

df.groupby("body_mention")['document_id'].apply(lambda x: ','.join(x))

# body_mention
# Bob    doc_01,doc_04
# Sam           doc_03
# Name: document_id, dtype: object

df.groupby("body_mention")['count'].sum()

#body_mention
# Bob    6
# Sam    1
# Name: count, dtype: int64

所以这两行:

    dfOut= pd.concat([df.groupby("body_mention")['count'].sum(),df.groupby("body_mention")['document_id'].apply(lambda x: ','.join(x)) ], axis=1)
    dfOut.to_csv('out.csv',sep = "|")

csv文件:

body_mention|count|document_id
Bob|6|doc_01,doc_04
Sam|1|doc_03