我是一名Python初学者,他试图获得给定类别的多个随机行。原始文件有三列,但我感兴趣的只是其中一个类别。文件(csv)如下所示:
No,Size,Name
10,1346,Cat
24,423,Dog
289,590,Cat
12,302,Dog
351,33,Cat
51,812,Dog
91,778,Cat
1193,465,Cat
44,178,Dog
没有一行是相同的,我想为每个'名字'获得随机的3行。这就是我到目前为止所做的:
import random
with open('C:\Users\Owl\file.csv') as f:
lines = f.readlines()[1:] #Skip heading
for line in lines:
try:
name = line[2]
except:
continue
for name in lines:
for lines in random.sample(lines,3):
print lines
f.close()
但我得到这样的东西:
12,302,Dog
1193,465,Cat
10,1346,Cat
2
3
D
而不是像这样:
1193,465,Cat
10,1346,Cat
91,778,Cat
51,812,Dog
44,178,Dog
12,302,Dog
在我现在得到的输出中,我没有通过'名字'得到线条,不知何故只是字母/数字。然后,我得到“ValueError:sample than population”并终止(实际文件比这里的例子大得多)。
另外,如果可能,是否有一种简单的方法可以按输出中的“名称”进行排序?
我一直在努力解决这个问题几个小时在互联网上查找,但一直无法解决......有人可以帮帮我吗?谢谢大家!
答案 0 :(得分:1)
使用itertools.groupby()
和the csv
module可以更轻松地完成此操作。我们首先制作csv.DictReader
以便我们轻松访问这些值,然后按"Name"
列对列表进行排序和分组,然后选择值。
import itertools
import csv
import operator
import random
with open("test.csv") as file:
data = csv.DictReader(file)
key = operator.itemgetter("Name")
for name, items in itertools.groupby(sorted(data, key=key), key):
print(name+":", random.sample(list(items), 3))
这给了我们:
Cat: [{'Size': '33', 'Name': 'Cat', 'No': '351'}, {'Size': '590', 'Name': 'Cat', 'No': '289'}, {'Size': '465', 'Name': 'Cat', 'No': '1193'}]
Dog: [{'Size': '178', 'Name': 'Dog', 'No': '44'}, {'Size': '812', 'Name': 'Dog', 'No': '51'}, {'Size': '302', 'Name': 'Dog', 'No': '12'}]
如果您想制作词典列表,可以使用简单的list comprehension轻松完成:
[[item["No"], item["Size"], item["Name"]] for item in items]
答案 1 :(得分:0)
你要覆盖很多变数:
name
中的for line in lines
从未使用过。你循环for name in lines
,然后不要使用name
但是开始第二个循环for lines in random.sample(lines, 3)
:你只是让Python感到困惑:什么是lines
现在?随机元素lines
..然后,你回到这个新元素循环。你可以尝试类似的东西:
for name in lines:
for row in random.sample(lines, 3):
...
这会有所帮助,但不是很多:你仍然在循环原始文件。
我建议你开始构建一个字典,存储每个name
names = defaultdict(list)
for line in lines:
fields = line.split()
names[fields[2]].append(line)
然后,对name
的每个names
,随机抽样为random.sample(names[name], 3)