0

別の形式に変換したいCSVファイルがあります。CSV形式は次のとおりです。

A_to_B,B_to_C,C_to_D,...
0,2,1,...

つまり、各見出しはAとBなどの2つの変数で構成され、ファイルの各行には0、1、または2のいずれかの値が含まれています。このCSVファイルを読み取るPythonスクリプトを作成しようとしています。次のような形式に変換します。

A,B,0
B,C,2
C,D,1
...

つまり、ヘッダーで構成される最初の行を変数(A、B、C、Dなど)に分割してから、新しい形式の対応する値と一致させます。誰かがこれを行う方法を知っていますか?基本的なことはいくつかありますが、実際のアルゴリズムでは頭をうまく動かすことができません。ご協力いただきありがとうございます。

更新#1

これが私がダウンしているいくつかのコードですが、正しい出力が得られません:

import csv,sys

reader = csv.reader(open(sys.argv[1], 'rt'), delimiter=',')
headers = reader.next()

data = []

for row in reader:
    line = ','.join(row)
    data.append(line)

for row in data:
    for cols, val in zip(headers, row):
        newRow = cols[0], cols[-1], val
        print newRow

CSVファイルは次のようになります。

A,B,C
0,2,1
0,1,1

ただし、コードの出力は次のようになります。そのため、CSVファイルを正しい方法で反復処理する方法が必要です。

('A', 'A', '0')
('B', 'B', ',')
('C', 'C', '2')
('A', 'A', '0')
('B', 'B', ',')
('C', 'C', '1')

更新#2

誰かがこれに遭遇した場合、これが私が最終的に得たコードです(エラー処理などはありませんが、機能します):

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

import csv,os,sys

reader = csv.reader(open(sys.argv[1], 'rt'), delimiter=',')
headers = reader.next()
i = 1

for row in reader:
    os.system('rm id' + str(i) + '.csv')
    os.system('cat ./seeds >> id' + str(i) + '.csv')
    for srcdest,dist in zip(headers, row):
        sd = srcdest.split('_to_')
        src,dest = sd[0],sd[-1]
        if dist == '0':
            pass
        else:
            f = open('id' + str(i) + '.csv', 'a')
            f.write('{},{},{}\n'.format(src.lower().replace('_',''),dest.lower().replace('_',''),float(dist)))
    i=i+1

f.close()

みなさん、ありがとうございました!

4

3 に答える 3

0
from itertools import izip

with open("myfile.csv") as inf, open("new.csv","w") as outf:
    header = [s.split('_to_') for s in inf.next().split(',')]
    for row in inf:
        nums = (int(s) for s in row.split(','))
        for (_from, _to), num in izip(header, nums):
            outf.write("{},{},{}\n".format(_from, _to, _num))
于 2012-06-04T02:15:53.773 に答える
0

1 つの可能性を次に示します。

>>> header
[u'A_to_B', u'B_to_C', u'C_to_D']
>>> data
[[0, 1, 2], [0, 2, 1], [1, 2, 3]]
>>> for row in data:
...     for cols, val in zip(header, row):
...         newRow = cols[0], cols[-1], val
...         print newRow
(u'A', u'B', 0)
(u'B', u'C', 1)
(u'C', u'D', 2)
(u'A', u'B', 0)
(u'B', u'C', 2)
(u'C', u'D', 1)
(u'A', u'B', 1)
(u'B', u'C', 2)
(u'C', u'D', 3)

示されているように、これは、列名のリストを持つ「ヘッダー」のものと、行のリストである「データ」のものがあることを前提としています。(これは基本的に、標準ライブラリの csv モジュールを使用した場合に得られるものです。) 行の新しいリストを出力します。

この例では、すべての列名が 1 文字であると仮定したため、"A_to_B" スタイルの列名の最初と最後の文字としてアクセスできました。cols.split('_')列名の長さが異なる場合は、区切り文字で分割して 2 つの列名を抽出することができます。しかし、それはあなたの主な質問に接する文字列解析の問題にすぎません。

編集に応じて編集します。

for最初のループを削除します。csv.reader からのデータは、既に必要な形式になっています。そうする','.join'ことで、それを望まない形式に再パッケージ化しています。2 番目の for ループは、リーダーを直接反復する必要があります。

>>> for row in reader:
...     for cols, val in zip(headers, row):
...         newRow = cols[0], cols[-1], val
...         print newRow

もう 1 つの問題は、編集で投稿したデータが元のデータと同じ形式ではないことです。最初に、列は「A_to_B」、「B_to_C」などの形式であると言いましたが、2番目の例では、列は単に「A」、「B」、「C」などです。どのように説明する必要がありますか元の列名から新しい列名を派生させるつもりです。

于 2012-06-04T00:24:56.703 に答える
0

次のようにデータを読み込みます。

row1 = ['A_to_B','B_to_C',...]
row2 = [0,2,1,...]

これは、ファイルを開き、行を読み取り、コンマで分割するだけで実行できます。csv標準ライブラリのモジュールを使用することもできます。それができたら、次のようなことができます:

for srcdest,dist in zip(row1,row2):
    sd = srcdest.split('_')
    src,dest = sd[0],sd[-1]
    f.write('{},{},{}\n'.format(src,dest,dist))

f宛先ファイルはどこにありますか。モジュールを使用しcsvて行を書き込むこともできますが、ファイルを書き込むだけの方が簡単な場合があります。

于 2012-06-04T00:35:40.233 に答える