Python:获取给定类别的多个随机行

时间:2012-09-27 21:50:57

标签: python random line categories

我是一名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”并终止(实际文件比这里的例子大得多)。

另外,如果可能,是否有一种简单的方法可以按输出中的“名称”进行排序?

我一直在努力解决这个问题几个小时在互联网上查找,但一直无法解决......有人可以帮帮我吗?谢谢大家!

2 个答案:

答案 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)