0

私はPythonの初心者で、特定のカテゴリに対して複数のランダムな行を取得しようとしています。元のファイルには3つの列がありますが、私が興味を持っているのはそれらのカテゴリの1つにすぎません。ファイル(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 large thanpopulation」を取得して終了します(実際のファイルはここの例よりもはるかに大きいです)。

また、可能であれば、出力の「名前」で並べ替える簡単な方法はありますか?

私はこれをインターネットで何時間も調べて苦労してきましたが、解決できませんでした...誰か助けてくれませんか?皆さん、ありがとうございました!

4

2 に答える 2

1

itertools.groupby()モジュールを使用するとcsvこれをはるかに簡単に行うことができます。まず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'}]

辞書リストを作成したい場合は、単純なリスト内包表記で簡単に行うことができます:

[[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に 2 番目のループを開始し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 に答える