我遇到了一个关于从TSV / CSV文件收集数据的循环的问题。 问题是我检查用户ID是否在我的tsv文件中,以及它是否只是进行常规打印。但问题是它没有加起来。
让我通过使用我现在直到的代码来解释自己:
import csv
with open("source/to/file.tsv") as tsvfile:
tsvreader = csv.reader(tsvfile, delimiter="\t")
for i in range(1,10):
for columns in tsvreader:
userid = 1
column1, column2, column3 = columns
if userid == int(column1):
print("userid:", userid,"result: ", int(column1), int(column2), int(column3))
userid += 1
每当我运行此代码时,它将输出:
-- userid: 1 result: 1 3098 1
-- userid: 1 result: 1 508 1
-- userid: 1 result: 1 889 1
-- userid: 1 result: 1 802 0
-- userid: 1 result: 1 3800 0
问题从这里开始。因为我希望我的用户ID加起来为1.我的用户ID将为2,循环将重新开始,并打印出类似的内容:
-- user id 2 result: ...
-- user id 2 result: ...
-- user id 2 result: ...
但我的代码不这样做。谁知道为什么?
请注意:userid 2在我的TSV文件中,所以这不是问题!
我的tsv文件中的额外信息:我遇到以下情况:
1 802 0
1 3800 0
2 7492 1
2 5235 0
我想输出属于userid1(802,3800等)的所有结果,之后循环必须继续输出userid2(7492,5235等)的所有结果。在此过程的后期,我想为每个用户ID存储他们的结果。
答案 0 :(得分:2)
代码重置每行的userid(即for columns in...
循环内)。如果你将那条线移到那个循环之外,我相信它会做你想要的。
答案 1 :(得分:2)
Rob's answer中解释了代码未超出用户标识1的原因。
在我看来,您打算打印userid 1的所有行,然后打印userid 2的所有行,依此类推。外循环上的范围表明您希望显示用户ID 1到9的行。
但有一个问题是,一旦使用了CSV文件中的所有行,for columns in tsvreader
循环将不再有任何迭代,因此它的主体将不会执行。将不再显示任何内容。这可以通过"倒带"来解决。输入文件为seek()
。
修复这些错误导致此代码:
import csv
with open("source/to/file.tsv") as tsvfile:
tsvreader = csv.reader(tsvfile, delimiter="\t")
for userid in range(1,10):
tsvfile.seek(0) # back to the start of the CSV file
for columns in tsvreader:
column1, column2, column3 = columns
if userid == int(column1):
print("userid:", userid,"result: ", int(column1), int(column2), int(column3))
我认为就是你所追求的。例如关于输入(我使用逗号作为分隔符):
2,4,4 1,2,3 1,4,5 2,8,8 1,6,7 2,2,2 4,1,1 8,1,2 10,4,0 1,0,1 4,4,4 3,3,3
输出结果为:
userid: 1 result: 1 2 3 userid: 1 result: 1 4 5 userid: 1 result: 1 6 7 userid: 1 result: 1 0 1 userid: 2 result: 2 4 4 userid: 2 result: 2 8 8 userid: 2 result: 2 2 2 userid: 3 result: 3 3 3 userid: 4 result: 4 1 1 userid: 4 result: 4 4 4 userid: 8 result: 8 1 2
请注意,不包括用户标识10的数据,因为它超出了用户标识范围。
我不得不猜测你的意图,但是,如果我是正确的,你想要做的是按用户ID对数据进行分组并按排序顺序显示。更好的方法是一次性对所有数据进行排序:
import csv
with open("source/to/file.tsv") as tsvfile:
data = sorted(list(csv.reader(tsvfile, delimiter='\t')),
key=lambda row: int(row[0]))
for column1, column2, column3 in data:
print("userid:", column1, "result: ", int(column1), int(column2), int(column3))
输出:
userid: 1 result: 1 2 3 userid: 1 result: 1 4 5 userid: 1 result: 1 6 7 userid: 1 result: 1 0 1 userid: 2 result: 2 4 4 userid: 2 result: 2 8 8 userid: 2 result: 2 2 2 userid: 3 result: 3 3 3 userid: 4 result: 4 1 1 userid: 4 result: 4 4 4 userid: 8 result: 8 1 2 userid: 10 result: 11 4 0
如果您确实要排除给定范围之外的用户ID,请执行以下操作:
import csv
with open("source/to/file.tsv") as tsvfile:
data = sorted(list(csv.reader(tsvfile, delimiter='\t')),
key=lambda row: int(row[0]))
userids = range(1,10)
for column1, column2, column3 in data:
if int(column1) in userids:
print("userid:", column1, "result: ", int(column1), int(column2), int(column3))
答案 2 :(得分:1)
我没有得到你想要做的事情,因为Rob Hague说你保持userid
为1 ......
猜测你想要什么:
userid = 1
tsv = csv.reader(open(filename), delimiter='\t')
for i, row in enumerate(tsv):
if i > 10:
break
if str(userid) == row[0]:
print 'userid: %d result: %s' % (userid, row)
userid+= 1
else:
print 'not found: %s' % (row,)
修改强>
简单的方法(我不会在示例中使用csv
模块,因为您似乎不需要它),但使用更多内存。
# load all data
import collections
data = collections.defaultdict(list)
for line in open(filename):
row = line.strip().split('\t')
data[int(row[0])]+= [row[1:]]
# output data grouped by user
for userid, row in data.iteritems():
print 'userid: %d result: %s' % (userid, row)
另一种简单的方法(假设数据由用户ID 排序),尽快输出结果并使用稍少的内存。
def show(userid, row):
print 'userid: %s result: %s' % (userid, row)
current = ''
data = []
for line in open(filename):
row = line.strip().split('\t')
if row[0] != current:
if data:
show(current, data)
del data[:]
current = row[0]
data+=[row]
show(row[0], data)
如果数据未排序且存在内存问题,您可以将位置存储在字典中并通过它存储seek
(参见file objects文档)。
答案 3 :(得分:0)
1 802 0
1 3800 0
2 7492 1
2 5235 0
我想输出属于userid1的所有结果(802,3800 等等,之后循环必须继续输出所有结果 userid2(7492,5235等)。在这个过程的后期我想为每个人存储 用户ID他们的结果。
您可以使用字典轻松完成您要实现的目标:
import csv
from collections import defaultdict
results_by_id = defaultdict(list)
with open('somefile.csv') as f:
reader = csv.reader(f, delimiter='\t')
for row in reader:
results_by_id[row[0]].append(list(map(int, row[1:])))
for userid, results in results_by_id.iteritems():
print('{} has {} total results'.format(userid, len(results)))
for result in results:
print('\t {}'.format(result))