5

まず、完全な開示:これは大学の課題に向かっているので、コードを受け取りたくありません。:)。私はアプローチをもっと探しています。私は本を​​読んだことがありますが、まだコードを書いていません

全体のタスクは、CSV ファイルの内容をインポートし、CSV ファイルの内容から ( ID3 アルゴリズムを使用して) 決定木を作成し、2 つ目の CSV ファイルを解析してその木に対して実行することです。さまざまな CSV ファイルを処理できるようにすることには大きな (理解できる) 好みがあります (列名をハードコーディングすることを許可するかどうかを尋ねましたが、主にそれを排除する可能性があるため、答えはノーでした)。

CSV ファイルはかなり標準的な形式です。ヘッダー行は # でマークされ、列名が表示され、その後のすべての行は単純な一連の値です。例:

# Column1, Column2, Column3, Column4
Value01, Value02, Value03, Value04
Value11, Value12, Value13, Value14

現時点では、CSV の解析という最初の部分を解決しようとしています。ディシジョン ツリーの決定を下すには、辞書構造が最も論理的であるように思われます。だから私はこれらの線に沿って何かをすることを考えていました:

Read in each line, character by character
If the character is not a comma or a space
    Append character to temporary string
If the character is a comma
    Append the temporary string to a list
    Empty string
Once a line has been read
    Create a dictionary using the header row as the key (somehow!)
    Append that dictionary to a list

ただし、そのようにすると、キーと値の間のマッピングを行う方法がわかりません。リスト内のすべてのディクショナリに対してアクションを実行する方法があるかどうかも疑問に思っています。誰が何を持っている!」・仕組みはあると思いますが、やり方がわからない。

辞書はそれを行うための最良の方法ですか?他のデータ構造を使用して物事を行うほうがよいでしょうか? もしそうなら、何?

4

7 に答える 7

4

docs.python.orgcsvのモジュールを使用した例:

import csv
reader = csv.reader(open("some.csv", "rb"))
for row in reader:
    print row

行をingする代わりにprint、各行をリストに保存し、後でID3で処理することができます。

database.append(row)
于 2010-04-28T03:24:03.663 に答える
4

Python には、非常に強力な言語構造が組み込まれています。次のようなファイルから行を読み取ることができます。

open(name_of_file,"r") をファイルとして使用:
    ファイルの行:
         # 行を処理する

string.split関数を使用して行をコンマで区切ることができ、string.stripを使用して間にある空白を削除できます。Python には非常に強力なリスト辞書があります。

リストを作成するには、[] のような空の括弧を使用します。空の辞書を作成するには、{} を使用します。

マイリスト = []; # 空のリストを作成します
mydict = {}; # 空の辞書を作成します

.append() 関数を使用してリストに挿入できますが、索引付け添え字を使用して辞書に挿入できます。たとえば、 を使用mylist.append(5)してリストに 5 を追加し、 を使用mydict[key]=valueしてキーkeyを値に関連付けることができますvalue。キーがディクショナリに存在するかどうかをテストするには、inキーワードを使用できます。例えば:

mydict のキーの場合:
   「現在」を印刷
そうしないと:
   「不在」を印刷

リストまたは辞書の内容を反復処理するには、次のように単純に for ループを使用できます。

mylist の val の場合:
    # val で何かをする

mydict のキーの場合:
    # キーまたは mydict[key] で何かを行う

多くの場合、リストを反復処理するときに値とインデックスの両方が必要になるため、enumerate という組み込み関数もあり、インデックスを自分でカウントする手間を省くことができます。

enumerate(mylist) の idx、val の場合:
    # val または idx を使用して何かを行います。val=mylist[idx] であることに注意してください

上記のコードは、次のものと機能が同じです。

idx=0
mylist の val の場合:
   # 処理 val, idx
   idx += 1

選択した場合は、インデックスを反復処理することもできます。

xrange(len(mylist)) の idx の場合:
    # idx と、場合によっては mylist[idx] で何かを行う

また、 lenを使用して、リスト内の要素の数または辞書内のキーの数を取得できます。

リスト内包表記を使用して、辞書またはリストの各要素に対して操作を実行できます。ただし、単純に for ループを使用してそのタスクを実行することをお勧めします。しかし、例として:

>>> list1 = 範囲(10)
>>> リスト1
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list2 = [list1 の x に対して 2*x]
>>>リスト2
[0、2、4、6、8、10、12、14、16、18]

時間があれば、 Python チュートリアルを読んで、より深い知識を得ることをお勧めします。

于 2010-04-28T01:02:05.903 に答える
2

csv.DictReaderを見てください。

例:

import csv
reader = csvDictReader(open('my_file.csv','rb') # 'rb' = read binary
for d in reader:
    print d # this will print out a dictionary with keys equal to the first row of the file.
于 2010-04-28T10:08:35.293 に答える
2

簡単な答え: (1) 組み込み csv モジュールの再実装 (2) csv モジュールのソース (C で記述されている) の読み取りに時間と精神的エネルギーを無駄にしないでください。使用するだけです。

于 2010-04-28T02:36:23.280 に答える
1

CSV を正しく解析する

str.split() は引用符で囲まれた値を認識しないため、str.split() を使用してフィールドを解析することは避けたいと思います。また、実際の CSV ファイルの多くは引用符を使用しています。 http://en.wikipedia.org/wiki/Comma-separated_values

引用符で囲まれた値を使用したレコードの例:

1997,Ford,E350,"Super, luxurious truck"

str.split() を使用すると、次のような 5 つのフィールドを持つレコードが得られます。

('1997', 'Ford', 'E350', '"Super', ' luxurious truck"')

しかし、本当に必要なのは、次のような 4 つのフィールドを持つレコードです。

('1997', 'Ford', 'E350', 'Super, luxurious truck')

また、データにカンマが含まれているだけでなく、改行 "\r\n" またはデータ内の "\n" のみを処理する必要がある場合もあります。例えば:

1997,Ford,E350,"Super
luxurious truck"
1997,Ford,E250,"Ok? Truck"

したがって、次の使用に注意してください。

file = open('filename.csv', 'r')
for line in file:
    # problem here, "line" may contain partial data

また、John が述べたように、CSV 標準は、引用符で囲まれている場合、二重引用符を取得すると、それが 1 つの引用符に変わるというものです。

1997,Ford,E350,"Super ""luxurious"" truck"

('1997', 'Ford', 'E350', 'Super "luxurious" truck')

したがって、有限状態マシンを次のように変更することをお勧めします。

  • 一度に各文字を解析します。
  • 引用かどうかを確認し、状態を「引用中」に設定します
  • 「in quote」の場合、別の引用があるまで現在のフィールドにすべての文字を保存します。
  • "in quote" で別の引用がある場合は、その引用文字をフィールド データに格納します。(空白のフィールドは `data,"",data` ではなく、代わりに `data,,data` であるべきなので、終わりではありません)
  • 「引用符で囲んで」いない場合は、コンマまたは改行が見つかるまで文字を保存します。
  • カンマの場合、フィールドを保存して新しいフィールドを開始します。
  • 改行の場合、フィールドを保存し、レコードを保存し、新しいレコードと新しいフィールドを開始します。

余談ですが、興味深いことに、CSV で # を使用してコメント アウトされたヘッダーを見たことがありません。したがって、私にとっては、データ内のコメント行も探す必要があるかもしれないことを意味します。# を使用して CSV ファイル内の行をコメント アウトすることは標準ではありません。

ヘッダー キーを使用して見つかったフィールドをレコード ディクショナリに追加する

メモリ要件にもよりますが、CSV が十分に小さい場合 (おそらく 10k から 100k レコード)、辞書を使用しても問題ありません。listインデックス(または番号)で列名にアクセスできるように、すべての列名を保存するだけです。次に、有限状態マシンで、コンマが見つかったときに列インデックスをインクリメントし、改行が見つかったときに 0 にリセットします。

したがって、ヘッダーがheader = ['Column1', 'Column2'] Then の場合、データ文字を見つけたら、次のように追加します。

record[header[column_index]] += character
于 2010-04-28T02:22:50.343 に答える
1

組み込みのCSV モジュールを見てください。あなたはおそらくそれを使用することはできませんが、コードをこっそり見ることができます...

それがダメなら、(疑似) コードは完全に問題ないように見えますが、str.split()関数を使用してそれを使用し、ファイルを 1 行ずつ読み取る必要があります。

于 2010-04-28T01:00:02.497 に答える
0

@Kaloyan Todorov が話している組み込みの csv モジュールについてはあまり知りませんが、カンマ区切りの行を読んでいる場合は、これを簡単に実行できます。

for line in file:
    columns = line.split(',')
    for column in columns:
        print column.strip()

これにより、先頭と末尾の空白なしで各行のすべてのエントリが出力されます。

于 2010-04-28T02:28:46.883 に答える