0

CSV (Web サイトから解析されたデータ) を生成する Python スクリプトがあります。CSV ファイルの例を次に示します。

File1.csv

China;Beijing;Auralog Software Development (Deijing) Co. Ltd.;;;
United Kingdom;Oxford;Azad University (Ir) In Oxford Ltd;;;
Italy;Bari;Bari, The British School;;Yes;
China;Beijing;Beijing Foreign Enterprise Service Group Co Ltd;;;
China;Beijing;Beijing Ying Biao Human Resources Development Limited;;Yes;
China;Beijing;BeiwaiOnline BFSU;;;
Italy;Curno;Bergamo, Anderson House;;Yes;

File2.csv

China;Beijing;Auralog Software Development (Deijing) Co. Ltd.;;;
United Kingdom;Oxford;Azad University (Ir) In Oxford Ltd;;;
Italy;Bari;Bari, The British School;;Yes;
China;Beijing;Beijing Foreign Enterprise Service Group Co Ltd;;;
China;Beijing;Beijing Ying Biao Human Resources Development Limited;;Yes;
This;Is;A;New;Line;;
Italy;Curno;Bergamo, Anderson House;;Yes;

ご覧のように、

中国;北京;BeiwaiOnline BFSU;;; ==> File1.csv のこの行は、File2.csv およびThis;Is;A;New;Line;には存在しません。==> File2.csv のこの行は新規です (File1.csv にはありません)。

この 2 つの CSV ファイルを比較する方法を探しています (知っておくべき重要なことの 1 つは、行の順序はカウントされないということです...どこにもないということです)。

私が欲しいのは、次のことを教えてくれるスクリプトです: - 1 つの新しい行: This;Is;A;New;Line;; - 削除された 1 行 :中国;北京;BeiwaiOnline BFSU;;; 等々 ... !

私は試しましたが、成功しませんでした:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import csv

f1 = file('now.csv', 'r')
f2 = file('past.csv', 'r')

c1 = csv.reader(f1)
c2 = csv.reader(f2)

now = [row for row in c2]
past = [row for row in c1]

for row in now:
    #print row
    lol = past.index(row)
    print lol

f1.close()
f2.close()

_csv.Error: new-line character seen in unquoted field - do you need to open the file in universal-newline mode?

続行するための最良の方法について何か考えはありますか? よろしくお願いします;)

編集:

import csv

f1 = file('now.csv', 'r')
f2 = file('past.csv', 'r')

c1 = csv.reader(f1)
c2 = csv.reader(f2)

s1 = set(c1)
s2 = set(c2)

lol = s1 - s2
print type(lol)
print lol

これは良い考えのようですが:

Traceback (most recent call last):
  File "compare.py", line 20, in <module>
    s1 = set(c1)
TypeError: unhashable type: 'list'

EDIT 2 (上にあるものは気にしないでください): *あなたの助けを借りて、ここに私が書いているスクリプトがあります: *

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import csv


### COMPARISON THING ###
x=0

fichiers = os.listdir('/me/CSV')
for fichier in fichiers:
    if '.csv' in fichier:
        print('%s -----> %s' % (x,fichier))
        x=x+1

choice = raw_input("Which file do you want to compare with the new output ? ->>>")
past_file = fichiers[int(choice)]
print 'We gonna compare %s to our output' % past_file

s_now = frozenset(tuple(row) for row in csv.reader(open('/me/CSV/now.csv', 'r'), delimiter=';')) ## OUR OUTPUT
s_past = frozenset(tuple(row) for row in csv.reader(open('/me/CSV/'+past_file, 'r'), delimiter=';')) ## CHOOSEN ONE

added = [";".join(row) for row in s_now - s_past]  # in "now" but not in "past"
removed = [";".join(row) for row in s_past - s_now]  # in "past" but not in "now"

c = csv.writer(open("CHANGELOG.csv", "a"),delimiter=";" )
line = ['AD']
for item_added in added:
    line.append(item_added)
    c.writerow(['AD',item_added])

line = ['RM']
for item_removed in removed:
    line.append(item_removed)
    c.writerow(line)

2 種類のエラー:

  File "programcompare.py", line 21, in <genexpr>
    s_past = frozenset(tuple(row) for row in csv.reader(open('/me/CSV/'+past_file, 'r'), delimiter=';')) ## CHOOSEN ONE
_csv.Error: line contains NULL byte

また

  File "programcompare.py", line 21, in <genexpr>
    s_past = frozenset(tuple(row) for row in csv.reader(open('/me/CSV/'+past_file, 'r'), delimiter=';')) ## CHOOSEN ONE
_csv.Error: newline inside string

数分前に動作していましたが、CSV ファイルを変更して別のデータでテストしました。ここにいます :-)

すみません、最後の質問です!

4

2 に答える 2

7

データが極端に大きくない場合は、セット (またはフリーズ セット)にロードするのが簡単な方法です。

s_now = frozenset(tuple(row) for row in csv.reader(open('now.csv', 'r'), delimiter=';'))
s_past = frozenset(tuple(row) for row in csv.reader(open('past.csv', 'r'), delimiter=';'))

追加されたエントリのリストを取得するには:

added = [";".join(row) for row in s_now - s_past]  # in "now" but not in "past"
# Or, simply "added = list(s_now - s_past)" to keep them as tuples.

同様に、削除されたエントリのリスト:

removed = [";".join(row) for row in s_past - s_now]  # in "past" but not in "now"

が表示されている理由に関する更新された質問に対処するために、csv は各エントリを反復時にTypeError: unhashable type: 'list'として返します。はハッシュ可能でないため、 に挿入できません。listlistsset

これに対処するには、 をセットに追加する前にlistエントリをに変換する必要があります。tupleこれを行う方法の例については、私の回答の前のセクションを参照してください。


表示されているその他のエラーに対処するには、どちらも CSV ファイルの内容が原因です。

_csv.Error: 文字列内の改行

"パーサーを混乱させるデータのどこかに引用符 ( ) があるようです。私は CSV モジュールに精通していないので、何がうまくいかなかったのかを正確に伝えることができません。

ただし、エラーを次のように再現することができました。

>>> [e for e in csv.reader(['hello;wo;"rld'], delimiter=";")]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_csv.Error: newline inside string

この場合、引用符で特別な処理を行わないようにリーダーに指示することで修正できます ( csv.QUOTE_NONEを参照)。(これにより、引用符で囲まれたデータの処理が無効になることに注意してください。これにより、文字列が個別のエントリに分割されることなく、区切り文字が引用符で囲まれた文字列内に表示されます。)

>>> [e for e in csv.reader(['hello;wo;"rld'], delimiter=";", quoting=csv.QUOTE_NONE)]
[['hello', 'wo', '"rld']]

_csv.Error: 行に NULL バイトが含まれています

これは、CSV ファイルのエンコーディングに起因する可能性があると推測しています。次の質問を参照してください。

于 2012-05-23T15:35:48.363 に答える
2

csv ファイルを 1 行ずつセットに読み取ります。セットを比較します。

>>> s1 = set('''China;Beijing;Auralog Software Development (Deijing) Co. Ltd.;;;
... United Kingdom;Oxford;Azad University (Ir) In Oxford Ltd;;;
... Italy;Bari;Bari, The British School;;Yes;
... China;Beijing;Beijing Foreign Enterprise Service Group Co Ltd;;;
... China;Beijing;Beijing Ying Biao Human Resources Development Limited;;Yes;
... China;Beijing;BeiwaiOnline BFSU;;;
... Italy;Curno;Bergamo, Anderson House;;Yes;'''.split('\n'))
>>> s2 = set('''China;Beijing;Auralog Software Development (Deijing) Co. Ltd.;;;
... United Kingdom;Oxford;Azad University (Ir) In Oxford Ltd;;;
... Italy;Bari;Bari, The British School;;Yes;
... China;Beijing;Beijing Foreign Enterprise Service Group Co Ltd;;;
... China;Beijing;Beijing Ying Biao Human Resources Development Limited;;Yes;
... This;Is;A;New;Line;;
... Italy;Curno;Bergamo, Anderson House;;Yes;'''.split('\n'))
>>> s1 - s2
set(['China;Beijing;BeiwaiOnline BFSU;;;'])
>>> s2 - s1
set(['This;Is;A;New;Line;;'])
于 2012-05-23T15:28:00.757 に答える