【问题标题】:Computing aggregate by creating nested dictionary on the fly通过动态创建嵌套字典来计算聚合
【发布时间】:2017-02-08 11:25:59
【问题描述】:

我是 python 新手,目前我真的可以使用您的帮助和指导。我正在尝试读取具有三个列的 csv 文件并根据第一列和第二列进行一些计算,即

A   spent   100     A   spent   2040
A   earned  60
B   earned  48
B   earned  180
A   spent   40
.
.
.

A 花费 2040 年将是所有“A”和“已花费”金额的加法。这不会给我一个错误,但它在逻辑上不正确:

for row in rows:
    cols = row.split(",")
    truck = cols[0]
    if (truck != 'A' and truck != 'B'):
        continue
    record = cols[1]
    if(record != "earned" and record != "spent"):
        continue
    amount = int(cols[2])
    #print(truck+" "+record+" "+str(amount))

    if truck in entries:
        #entriesA[truck].update(record)
        if record in records:
            records[record].append(amount)
        else:
            records[record] = [amount]
    else:
        entries[truck] = records
        if record in records:
            records[record].append(amount)
        else:
            entries[truck][record] = [amount]
print(entries)

我知道这部分是不正确的,因为我会将相同的内部字典列表添加到外部字典中,但我不确定如何从那里开始:

entries[truck] = records
if record in records:
    records[record].append(amount)

但是,我不确定动态创建一个不是“记录”的新字典的语法

我得到:

{'B': {'earned': [60, 48], 'spent': [100]}, 'A': {'earned': [60, 48], 'spent': [100]}}

但希望得到:

{'B': {'earned': [48]}, 'A': {'earned': [60], 'spent': [100]}}

谢谢。

【问题讨论】:

  • 这个术语是“A 的总支出是 2040 年”。是的,熊猫包可以做到这一点,强烈推荐。
  • 更好地表述问题“如何计算聚合?”,而不是询问实现“创建嵌套字典”。了解拆分应用组合范例。
  • 在您的预期结果中,为什么您认为 B 的收入是 48 而不是 228?同样对于A花费,不应该是140吗?您在问题中提到了总和,但现在看来您只想要第一个?

标签: python pandas dictionary group-by aggregate


【解决方案1】:

对于您在这里进行的计算,我强烈推荐Pandas

假设in.csv 看起来像这样:

truck,type,amount
A,spent,100
A,earned,60
B,earned,48
B,earned,180
A,spent,40

你可以用三行代码求和:

import pandas
df = pandas.read_csv('in.csv')
totals = df.groupby(['truck', 'type']).sum()

totals 现在看起来像这样:

              amount
truck type          
A     earned      60
      spent      140
B     earned     228

您会发现,Pandas 可以让您在更高层次上思考,避免在这种情况下摆弄较低层次的数据结构。

【讨论】:

    【解决方案2】:
    if record in entries[truck]:
        entries[truck][record].append(amount)
    else:
        entries[truck][record] = [amount]
    

    我相信这就是你想要的?现在我们直接访问卡车的记录,而不是尝试检查名为records 的本地字典。就像没有卡车进入时所做的那样。

    【讨论】:

    • 谢谢@Nysten,但我还是有同样的问题
    猜你喜欢
    • 2015-02-18
    • 1970-01-01
    • 2017-11-15
    • 2011-05-13
    • 2022-01-03
    • 2021-04-04
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    相关资源
    最近更新 更多