1

次のようなファイル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])
4

1 に答える 1