0

我是一名 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:样本大于总体”并终止(实际文件比此处的示例大得多)。

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

我已经为此苦苦挣扎了几个小时,在互联网上查找它,但未能解决......有人可以帮助我吗?谢谢你们!

4

2 回答 2

1

itertools.groupby()通过使用和模块csv您可以更轻松地做到这一点。我们首先制作 acsv.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'}]

如果您想制作字典列表,只需简单的列表推导即可轻松完成:

[[item["No"], item["Size"], item["Name"]] for item in items] 
于 2012-09-27T22:02:59.323 回答
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)

于 2012-09-27T22:02:27.457 回答