【问题标题】:Counting Based on Occurrences of a Dictionary's Key in a .CSV File根据 .CSV 文件中字典键的出现次数进行计数
【发布时间】:2012-10-29 10:26:18
【问题描述】:

我有一个看起来像这样的字典:

{100002: "['Apple', 'M', 'R', '500001', 'Fruit', '90']", 100004: "['Banana', 'M', 'Y', '500001', 'Fruit', '75']"}

键是整数,值是字符串。

我有一个如下所示的 .csv 文件:

100001,1
100001,1
100001,2
100002,1
100002,1
100002,3
100002,3
100003,1
100003,4
100004,2
100004,3
100004,3

我想计算给定键的第二列中每个数字的出现次数,并将该计数添加到我的字典中。因此,对于这个样本,100001 的 1 计数为 2,2 的计数为 1,100002 的计数为 1 的计数为 2,3 的计数为 2,100003 的计数为 1 的计数为 1,4 的计数为 1,100004 的计数为2 的计数为 1,3 的计数为 2。虽然此 .csv 文件包含各种键的数据(其中我的 dict 中的键是一个子集),但我想将这些计数附加到我的 dict 以便它看起来像这样(为每个键添加 4 个新值,按顺序为数字 1-4 的计数各一个。)

{100002: "['Apple', 'M', 'R', '500001', 'Fruit', '90', '2', '0', '2', '0']", 100004: "['Banana', 'M', 'Y', '500001', 'Fruit', '75', '0', '1', '2', '0']"}

这 4 个添加的部分是数字 1-4 的计数,因此 100002 具有 '2', '0', '2', '0',因为在 .csv 文件中有 2 行 100002,1 但 0 行带有 100002,2 和 2 行带有 @ 987654327@ 但 0 行与 100002,4

我的问题有两个部分。 1)如何计算 .csv 文件中一个键后跟一个 1-4 的数字的次数,以便我有 4 个计数(数字 1-4 各一个)? 2) 如何将这些计数添加到我的字典中?

答案:

根据接受的答案,我制作了这个。它比我想要的要丑一些,但我设法完成了工作。

dd = defaultdict(lambda: defaultdict(int))
with open('AgentsCorpLevel.csv') as fin:
    csvin = csv.reader(fin)
    for row in csvin:
        if int(row[0]) in MyDict.keys():
            dd[int(row[0])][row[1]] += 1
print dd
dicts = MyDict,dd
#print dicts
FullDict = {}
PartlyCleanedDict = {}
CleanedDict = {}
TwoTypeDict = {k:[d.get(k) for d in dicts] for k in {k for d in dicts for k in d}}
for key, value in TwoTypeDict.iteritems():
    FullDict.setdefault((int(key)), str(value))
for key, value in FullDict.iteritems():
    PartlyCleanedDict.setdefault((int(key)), value.translate(None, "[]{()\/\'\"<>").replace('}',',}'))
for key, value in PartlyCleanedDict.iteritems():
    CleanedDict.setdefault((int(key)), value.replace(',defaultdicttype int', ''))
print CleanedDict

ddprint 看起来像这样

defaultdict(<function <lambda> at 0x00000000025C3518>, {1000164: defaultdict(<ty
pe 'int'>, {'1': 12, '3': 5, '2': 17, '4': 10}), 1000103: defaultdict(<type 'int
'>, {'1': 3, '3': 3, '2': 3, '4': 3}), 1000137: defaultdict(<type 'int'>, {'1':
5, '3': 4, '2': 7, '4': 1}), 1000140: defaultdict(<type 'int'>, {'1': 28, '3': 2
6, '2': 33, '4': 8}), 1000143: defaultdict(<type 'int'>, {'1': 1, '3': 3, '2': 1
, '4': 1}), 1000149: defaultdict(<type 'int'>, {'1': 6, '3': 7, '2': 9, '4': 6})
, 1000150: defaultdict(<type 'int'>, {'1': 13, '3': 11, '2': 22, '4': 12}), 1000
132: defaultdict(<type 'int'>, {'1': 2, '3': 4, '2': 4, '4': 1}), 1000155: defau
ltdict(<type 'int'>, {'1': 10, '3': 4, '2': 2, '4': 3}), 1000158: defaultdict(<t
ype 'int'>, {'1': 6, '3': 1, '2': 7, '4': 5})})

不幸的是,我尝试完全“清理”生成的 CleanedDict 并没有奏效,因为这里是 CleanedDict 的 print 的示例(请注意,我在这里只提供 3 个键,并且我已经更改了适合我样品中水果和蔬菜主题的名称。

{1000132: 'Kiwi, S, B, 500006, Fruit, 3n, defaultdicttype int, 1: 2, 3: 4, 2: 4, 4: 1,}', 1000103: 'Iceberg Lettuce, M, G, 500004, Vegetable, 2n, defaultdicttype int, 1: 3, 3: 3, 2: 3, 4: 3,}',1000137: 'Pineapple, M, Y, 500006, Fruit, 45n,defaultdicttype int, 1: 5, 3: 4, 2: 7, 4: 1,}'}

【问题讨论】:

  • 我可以建议您对数据进行更多结构化吗?拥有数字键和总和令人困惑 - 我建议使用 dicts 的 dict,内部 dict 将计数存储为键,将它们的频率存储为值。
  • 我不反对一些额外的数据结构,但我不知道如何去做你的建议。这个 count number: frequency 的字典如何处理我已经拥有的数据作为我的主字典的值而不覆盖它?

标签: python string csv dictionary


【解决方案1】:

您可以使用嵌套的defaultdict - 我会将超过 4 个值的微调和处理以及确切的格式等...留给您...

import csv
from collections import defaultdict

d = {100002: "['Apple', 'M', 'R', '500001', 'Fruit', '90']", 100004: "['Banana', 'M', 'Y', '500001', 'Fruit', '75']"}
dd = defaultdict(lambda: defaultdict(int))
with open('test.csv') as fin:
    csvin = csv.reader(fin)
    for row in csvin:
        dd[int(row[0])][row[1]] += 1

for key in (key for key in dd if key in d):
    counts = [0] * 4
    for idx, val in dd[key].iteritems():
        counts[int(idx) - 1] = int(val)
    print key, d[key], counts

# 100002 ['Apple', 'M', 'R', '500001', 'Fruit', '90'] [2, 0, 2, 0]
# 100004 ['Banana', 'M', 'Y', '500001', 'Fruit', '75'] [0, 1, 2, 0]

【讨论】:

  • 一个坚实的开始 :) 这会产生一个错误:counts[int(idx) - 1] = int(val) IndexError: list assignment index out of range
  • 我得到了一些基于此的工作,你的答案是唯一的,所以你得到'接受':)
猜你喜欢
  • 2022-01-10
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2015-09-06
  • 2016-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多