【问题标题】:Group certain columns and summing up another column from a CSV对某些列进行分组并总结 CSV 中的另一列
【发布时间】:2019-01-29 13:19:47
【问题描述】:

我在 csv 中有需要解析的数据。它看起来像:

Date,Tag,Amount
13/06/2018,ABC,6750000
13/06/2018,ABC,159800
24/05/2018,ABC,-1848920
16/05/2018,AB,-1829700
16/05/2018,AB,3600000
28/06/2018,A,15938000
16/05/2018,AB,3748998
28/06/2018,A,1035000
28/06/2018,A,1035000
14/06/2018,ABC,2122717

您可以看到每个日期旁边都有一个标签和数字。 我想要实现的是按日期和标签制作日期并标记键和分组并总结金额。

预期结果

Date,Tag,Amount
13/06/2018,ABC,5220680
16/05/2018,AB,5519298
28/06/2018,A,18008000
14/06/2018,ABC,2122717

我现在使用的代码在下面,它不起作用。

from collections import defaultdict
import csv

d = defaultdict(int)

with open("file.csv") as f:
    for line in f:
        tokens = [t.strip() for t in line.split(",")]
        try:
            date = int(tokens[0])
            tag = int(tokens[1])
            amount = int(tokens[2])
        except ValueError:
            continue
        d[date] += amount

print d

有人可以告诉我如何在不使用熊猫的情况下实现这一点

【问题讨论】:

    标签: python python-3.x csv


    【解决方案1】:

    您绝对应该使用pandas。除了您必须自己编写代码之外,您只需安装 pandas 模块,将其导入 (import pandas as pd) 即可通过 2 行简单直观的代码解决此问题

    >>> df = pd.read_csv('file.csv')
    >>> df.groupby(['Date', 'Tag']).Amount.sum()
    
    Date        Tag
    13/06/2018  ABC     6909800
    14/06/2018  ABC     2122717
    16/05/2018  AB      5519298
    24/05/2018  ABC    -1848920
    28/06/2018  A      18008000
    

    如果你真的需要自己编写代码,你可以使用嵌套的defaultdict,这样你就可以有两层groupby。另外,为什么您尝试投射到int datetag?完全没有意义。只需将其删除。

    d = defaultdict(lambda: defaultdict(int))
    
    for line in z:
        tokens = [t.strip() for t in line.split(",")]
        try:
            date = tokens[0]
            tag = tokens[1]
            amount = int(tokens[2])
        except ValueError as e:
            continue
        d[date][tag] += amount
    

    输出是:

    13/06/2018 ABC 6909800
    24/05/2018 ABC -1848920
    16/05/2018 AB 5519298
    28/06/2018 A 18008000
    14/06/2018 ABC 2122717
    

    要输出上面的结果,只需遍历项目:

    for k,v in d.items():
        for k2, v2 in v.items():
            print(k,k2,v2)
    

    为了使您的代码更加出色,请仅阅读第一行,然后从第二行开始迭代直到结束。这样,您的 try/except 可以被删除,您将获得更简单、更清晰的代码。但是你可以从这里接,对吧? ;)

    要写入 csv,只需

    s = '\n'.join(['{0} {1} {2}'.format(k, k2, v2) for k,v in d.items() for k2,v2 in v.items()])
    with open('output.txt', 'w') as f:
        f.write(s)
    

    【讨论】:

    • 我需要在不使用熊猫的情况下实现这一目标
    • @R.Dave 好的.. 在这种情况下,您只需更改一个简单的细节。将编辑
    • 谢谢你的例子,你能不能帮我把结果输出成 csv 而不是打印?
    • 我认为您的示例没有将日期与标签分组并总结金额。我之前给过的
    • @R.Dave 是的,看看输出!这是您发布的预期 :) 添加了写入 csv 的示例。
    【解决方案2】:

    这是一种使用简单迭代的方法。

    例如:

    from collections import defaultdict
    import csv
    
    result = defaultdict(int)
    with open(filename) as infile:
        reader = csv.reader(infile)
        header = next(reader)
        for line in reader:
            result[tuple(line[:2])] += int(line[2])
    
    print(header)
    for k, v in result.items():
        print(k[0], k[1], v)
    

    输出:

    14/06/2018 ABC 2122717
    13/06/2018 ABC 6909800
    28/06/2018 A 18008000
    16/05/2018 AB 5519298
    24/05/2018 ABC -1848920
    

    转为 CSV

    with open(filename, "wb") as outfile:
        writer = csv.writer(outfile)
        writer.writerow(header)
        for k, v in result.items():
            writer.writerow([k[0], k[1], v])
    

    【讨论】:

    • 嗨,Rakesh,你上面的例子是对日期和标签列进行分组并总结金额列吗?
    • 是的...tuple(line[:2]) 是日期和标签。 line[2]是金额
    【解决方案3】:

    你可以使用itertools.groupby:

    from itertools import groupby 
    import csv
    header, *data = csv.reader(open('filename.csv'))
    new_data = [[a, list(b)] for a, b in groupby(sorted(data, key=lambda x:x[:2]), key=lambda x:x[:2])]
    results = [[*a, sum(int(c) for *_, c in b)] for a, b in new_data]
    with open('calc_results.csv', 'w') as f:
      write = csv.writer(f)
      write.writerows([header, *results])
    

    输出:

    Date,Tag,Amount
    13/06/2018,ABC,6909800
    14/06/2018,ABC,2122717
    16/05/2018,AB,5519298
    24/05/2018,ABC,-1848920
    28/06/2018,A,18008000
    

    【讨论】:

      猜你喜欢
      • 2021-04-29
      • 1970-01-01
      • 1970-01-01
      • 2021-05-08
      • 2014-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多