2

我正在解析一个 csv 文件来执行一些基本的数据处理。我正在使用的文件是网站的用户活动日志,格式如下:

User ID, Url, Number of Page Loads, Number of Interactions 

用户 ID 和 URL 是字符串,页面加载次数和交互次数是整数。

我正在尝试确定哪个 url 具有最佳的交互页面比率。

我正在努力的部分是获取唯一值并汇总列中的结果。

我编写了以下代码:

import csv
from collections import defaultdict

fields = ["USER","URL","LOADS","ACT"]

file = csv.DictReader(open('file.csv', 'rU'), delimiter=",",fieldnames=fields)
file.next()

dict = defaultdict(int)

for i in dict:
    dict[i['URL']] += int(i['LOADS'])

这工作正常。它返回一个唯一 url 列表,其中包含字典中 url 的总加载数 -{ 'URL A' : 1000 , 'URL B' : 500}

问题是当我尝试向 url 键添加多个值时,我很难过。

我试过修改for循环来做:

for i in dict:
    dict[i['URL']] += int(i['LOADS']), int(i['ACT'])

我收到了TypeError: unsupported operand type(s) for +=: 'int' and 'tuple'。为什么第二个值被认为是一个元组?

我尝试添加 just int(i[ACT]),效果很好。就在我同时尝试这两个值的时候。

我在 python 2.6.7;关于如何做到这一点以及为什么将其视为元组的任何想法?

4

4 回答 4

1

因为int(i['LOADS']), int(i['ACT'])是一个元组:

>>> 1, 2
(1, 2)

如果要同时添加两个变量,只需将它们相加即可:

+= int(i['LOADS']) + int(i['ACT'])

此外,您正在遮蔽内置函数dictlist类型。使用不同的变量名称。list一旦你的影子你将无法使用内置:

>>> d = {1: 2, 3: 4}
>>> list(d)
[1, 3]
>>> list = 5
>>> list(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
于 2013-01-08T14:44:29.133 回答
1

就在我同时尝试这两个值的时候。

你想如何“添加”它们?作为他们的总和?

for i in list:
    dict[i['URL']] += int(i['LOADS']) + int(i['ACT'])

另外,不要使用listanddict作为变量名。

import csv
fields = ["USER","URL","LOADS","ACT"]

d = {}
with open('file.csv', 'rU') as f:
    csvr = csv.DictReader(f, delimiter=",",fieldnames=fields)
    csvr.next()
    for rec in csvr:
        d[rec['URL']] = d.get(rec['URL'], 0) + int(rec['LOADS']) + int(rec['ACT'])
于 2013-01-08T14:44:36.127 回答
1

你最好使用 alist作为你的 defaultdict 容器:

import csv
from collections import defaultdict

d = defaultdict(list)
fields = ["USER","URL","LOADS","ACT"]

with open('file.csv', 'rU') as the_file:
    rows = csv.DictReader(the_file, delimiter=",",fieldnames=fields)
    rows.next()

    for row in rows:
        data = (int(row['LOADS']),int(row['ACT']))
        d[row['URL']].append(data)

现在你有

d['someurl'] = [(5,17),(7,14)]

现在你可以做任何你想做的总和,例如,loads一个 URL 的所有:

load_sums = {k:sum(i[0] for i in d[k]) for k in d}
于 2013-01-08T14:53:26.663 回答
1

您可以使用面向对象的方法并定义一个类来保存信息。它比大多数其他答案更冗长,但值得考虑。

import csv
from collections import defaultdict

class Info(object):
    def __init__(self, loads=0, acts=0):
        self.loads = loads
        self.acts = acts
    def __add__(self, args): # add a tuple of values
        self.loads += args[0]
        self.acts += args[1]
        return self
    def __repr__(self):
        return '{}(loads={}, acts={})'.format(self.__class__.__classname__,
                                              self.loads, self.acts)

summary = defaultdict(Info)
fields = ["USER", "URL", "LOADS", "ACTS"]

with open('urldata.csv', 'rU') as csv_file:
    reader = csv.DictReader(csv_file, delimiter=",", fieldnames=fields)
    reader.next() # skip header
    for rec in reader:
        summary[rec['URL']] += (int(rec['LOADS']), int(rec['ACTS']))

for url,info in summary.items():
    print '{{{!r}: ({}, {})}}'.format(url, info.loads, info.acts)
于 2013-01-08T17:38:19.607 回答