次のようなファイルdata.csvがあります(A と B の 2 つの列):
A B
01 a
'b'
0101 a
b
010101 a
'b'
'c'
d
'e'
f
010102 a
b
'd'
'e'
010201 a
b
'c'
d
02 a
b
0201 a
b
020101 a
b
'd'
'e'
020102 a
'b'
c
020201 a
b
c
d
'e'
020301 a
'b'
c
d
次のように表示したい (5 つの列、A、B、C、D、E):
A B C D E
01 a b
0101 a b
010101 a b c d, e, f
010102 a b d, e
010201 a b c d
02 a
0201 a b
020101 a b d, e
020102 a b c
020201 a b c d, e
020301 a b c d
これは私がdata.csvについて知っていることです:
- UTF-8 エンコーディング
- UNIX スタイルの行末
- タビュレーター区切り文字
- 一部の行が空白です (空のセル)
- 一部の行は空のセル(タブレータ)で始まります
- 一部の行は 2 桁、4 桁、または 6 桁で始まります
- 一部のセルにはテキスト文字列が含まれており、ここでは 1 文字で表されています
- 一部の文字列は ' 記号で囲まれています
- 「a」、「b」、「c」の値が常に存在するとは限りません
- 「a」、「b」、または「c」のパターンはありません
- 「d」、「e」、「f」にはパターンがあります - 単語
foo
はそれらの文字列の一部です
data.csvをテキスト ファイルとして扱い、次のスクリプトを作成します。
- 空行を削除する
- タブ文字 (空のセル) で始まる行を前の行に追加する
- ' 記号を削除します
コード:
#!/usr/bin/python3
f = open('data.csv')
c = f.read()
f.close()
c = c.replace('\n\n', '\n')
c = c.replace('\n\t', '\t')
c = c.replace("'", "")
f = open('output.csv', 'w')
f.write(c)
f.close()
...そして、私は立ち往生しました。csv
おそらく、モジュールを使用して、他の調整と一緒にこれを行うためのより統一された方法があります。これを Python 3.3 で解決するにはどうすればよいですか (どの 3.x ソリューションも互換性があると思います)。
アップデート
Martijn Pieter の回答に基づいて、私はこれを思いつきましたが、「a」、「b」、および「c」のテキスト値が常に適切な列に配置されているかどうかはわかりませんが、機能しているようです。また、最後の行はスキップ/空白のままになります。
#!/usr/bin/python3
import csv
with open('input.csv', newline='') as infile, open('output.csv', 'w', newline='') as outfile:
reader = csv.reader(infile, delimiter='\t')
writer = csv.writer(outfile, delimiter='\t')
write_this_row = None
for row in reader:
# If there is a row with content...
if row:
# If the first cell has content...
if row[0]:
if write_this_row != None:
writer.writerow(write_this_row)
write_this_row = row
elif 'foo' in row[1]:
if len(write_this_row) < 5:
write_this_row.extend([''] * (5 - len(row)))
if write_this_row[4]:
write_this_row[4] += ';' + row[1]
else:
write_this_row[4] = row[1]
else:
write_this_row.insert(3, row[1])