我正在解析csv文件以执行一些基本的数据处理。我正在使用的文件是一个用户活动日志,其格式如下:
User ID, Url, Number of Page Loads, Number of Interactions
用户ID和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 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'
。为什么第二个值被视为元组?
我尝试添加int(i[ACT])
,但效果很好。就在我同时尝试这两个值的时候。
我在python 2.6.7上;关于如何做到这一点以及为什么它被视为元组的任何想法?
答案 0 :(得分:1)
因为int(i['LOADS']), int(i['ACT'])
是一个元组:
>>> 1, 2
(1, 2)
如果您想同时添加两个变量,只需将它们一起添加:
+= int(i['LOADS']) + int(i['ACT'])
此外,您正在隐藏内置dict
和list
类型。使用不同的变量名称。一旦你的影子,你将无法使用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
答案 1 :(得分:1)
只是当我同时尝试这两个值时。
你想如何&#34;添加&#34;他们?作为他们的总和?
for i in list:
dict[i['URL']] += int(i['LOADS']) + int(i['ACT'])
另外,请勿使用list
和dict
作为变量名称。
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'])
答案 2 :(得分:1)
最好使用list
作为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)]
现在你可以做任何你想要的总和,例如,URL的所有loads
:
load_sums = {k:sum(i[0] for i in d[k]) for k in d}
答案 3 :(得分: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)