0

私は初心者のコーダーで、Python csv モジュールを使用して csv ファイルを解析しているときに問題が発生しました。問題は、最初のフィールドを除くすべての行のフィールド値が「なし」であるという出力が表示されることです。

これは、解析しようとしている醜い csv ファイルの最初の行です (残りの行は同じ形式に従います)。

0,213726,NORTH FORK SLATE CREEK,CAMPGROUND,North Fork Slate Creek Campground | Idaho |      Public Lands Information Center | Recreation Search, http://www.publiclands.org/explore/site.php?plicstate=ID&id=2268,NA,NA,NA,NA,(208)839-2211,"Nez Perce National Forest  Operating Days: 305<br>Total Capacity: 25<br>

5 campsites at the confluence of Slate Creek and its North Fork. A number of trails form loops in the area. These are open to most traffic, including trail bikes.","From Slate Creek, go 8 miles east on Forest Road 354.",NA,http://www.publiclands.org/explore/reg_nat_forest.php?region=7&forest_name=Nez%20Perce%20National%20Forest,NA,NA,NA,45.6,-116.1,NA,N,0,1103,2058

csv ファイルを解析するために私が書いたコードは次のとおりです (正しく動作しません!)。

import csv

#READER SETTINGS
f_path = '/Users/foo'
f_handler = open(f_path, 'rU').read().replace('\n',' ')
my_fieldnames = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7', 
'col8', 'col9', 'col10', 'col11', 'col12', 'col13', 'col14', 'col15', 
'col16', 'col17', 'col18', 'col19', 'col20', 'col21', 'col22', 'col23', 
'col24','col25']
f_reader = csv.DictReader(f_handler, fieldnames=my_fieldnames, delimiter=',', dialect=csv.excel)

#NOW I TRY TO PARSE THE CSV FILE
i = 0
for row in f_reader:
    print "my first row was %s" % row
    i = i + 1
    if i > 0:
        break

そして、これが出力です。最初のフィールドを除くすべてのフィールドが空白であると表示されますが、その理由はわかりません! どんな提案でも大歓迎です。

my first row was {'col14': None, 'col15': None, 'col16': None, 
'col17': None, 'col10': None, 'col11': None, 'col12': None, 
'col13': None, 'col18': None, 'col19': None, 'col2': None, 'col8': None, 
'col9': None, 'col6': None, 'col7': None, 'col4': None, 'col5': None, 
'col3': None, 'col1': '0', 'col25': None, 'col24': None, 
'col21': None, 'col20': None, 'col23': None, 'col22': None}
4

3 に答える 3

3

さまざまなソフトウェア システムが CSV と呼ぶものの世界は大きく異なります。幸いなことに、Python の優れた CSV モジュールはこれらの詳細を非常にうまく処理できるため、手動で処理する必要はありません。

@metapertureの回答を使用したが、説明されていないいくつかのことを強調させてください。方言を自動検出することにより、PythonでCSVファイルを読み取ることによる推測をすべて回避できます。その部分を釘付けにすれば、それ以上うまくいかないことはほとんどありません。

簡単な例を挙げましょう。

    import csv

    with open(filename, 'rb') as csvfile:
        dialect = csv.Sniffer().sniff(csvfile.read(10024))
        csvfile.seek(0)
        qreader = csv.reader(csvfile, dialect)
        cnt = 0
        for item in qreader:
            if cnt >0:
                #process your data
            else:
                #the header of the csv file (field names)    
            cnt = cnt + 1
于 2013-05-07T15:57:27.263 に答える
0

あなたがするとき:

f_handler = open(f_path, 'rU').read().replace('\n',' ')

すべての改行を削除しています。これは、 csv.excel 方言が新しい行を検出する方法です。ファイルには 1 行しかないため、返されるのは 1 回だけです。

さらに、あなたはやっています:

if i > 0:
    break

最初の反復後に for ループを終了します。

空白の理由については、デフォルトの restval が None ( http://docs.python.org/3.2/library/csv.htmlを参照) であるため、キーが一致していない可能性があります。fieldnames 引数を含めないようにしてください。おそらく、この方言のキーが「col2」、「col3」などの行に沿っていることがわかります。

私が使用するかわいい小さなラッパー:

def iter_trim(dict_iter):
#return (dict(zip([k.strip(" \t\n\r") for k in row.keys()], [v.strip(" \t\n\r") for v in row.values()])) for row in dict_iter)
 for row in dict_iter:
    try:
        d =  dict(zip([k.strip(" \t\n\r") for k in row.keys()], [v.strip(" \t\n\r") for v in row.values()]))
        yield d
    except:
        print "row error:"
        print row

使用例:

def csv_iter(filename):
    csv_fp = open(filename)
    guess_dialect = csv.Sniffer().sniff(csv_fp.read(16384))
    csv_fp.seek(0)
    csv_reader = csv.DictReader(csv_fp,dialect=guess_dialect)
    return iter_trim(csv_reader)
for row in csv_iter("some-file.csv"):
    # do something...
    print row
于 2013-05-07T15:27:46.420 に答える