0

**私の目標はcsvモジュールのインポートを避けることです

非常に大きなcsvファイルを実行し、行を新しいcsvファイルに選択的に書き込むスクリプトに取り組んでいます。

次の2行があります。

with open(sys.argv[1]) as ifile, open(sys.argv[2], mode = 'w') as ofile:
    for row in ifile: 

そして、これ、いくつかのネストされた if ステートメントがダウンします。

line = list(ifile)[row]
ofile.write(line)

私はそれが正しくないことを知っています-私はそれを突き刺し、ここの誰かがこれを正しく行う方法についていくつかの光を当てることができることを望んでいました. この質問の本質は、「ofile」を使用して新しい csv ファイルに書き出せるように、現在の行を参照する方法です。さらに説明が必要な場合はお知らせください。ありがとう!

編集: Pastebin リンクに含まれる完全なコード - http://pastebin.com/a0jx85xR

4

2 に答える 2

0

あなたはかなり近いです。これはあなたがしなければならないすべてです:

with open(sys.argv[1]) as ifile, open(sys.argv[2], mode = 'w') as ofile:
    for row in ifile:

    #...
    #You've defined some_condition to be met (you will have to replace this for yourself)
    #E.g.: the number of entries in each row is greater than 5:
        if len([term for term in row.split('#') if term.strip() != '']) > 5:
            ofile.write(row)

アップデート:

行の分割に関するOPの質問に答えるには:

Python では、区切り文字を指定して行を分割します。これは CSV ファイルであるため、行を,. 例:

これが行 (文字列) の場合:

0, 1, 2, 3, 4, 5

適用する場合:

line.split(',')

リストを取得します:

['0', '1', '2', '3', '4', '5']

更新 2:

import sys

if __name__ == '__main__':
    ticker = sys.argv[3]
    allTypes = bool(int(sys.argv[4])) #argv[4] is a string, you have to convert it to an int, then to a bool

    with open(sys.argv[1]) as ifile, open(sys.argv[2], mode = 'w') as ofile:
        all_timestamps = [] #this is an empty list
        n_rows = 0
        for row in ifile:
            #This splits the line into constituent terms as described earlier
            #SAMPLE LINE:
            #A,1,12884902522,B,B,4900,AAIR,0.1046,28800,390,B,AARCA,
            #After applying this bit of code, the line should be split into this:
            #['A', '1', '12884902522', 'B', 'B', '4900', 'AAIR', '0.1046', '28800', '390', 'B', 'AARCA']
            #NOW, you can make comparisons against those terms. :)

            terms = [term for term in row.split(',') if term.strip() != '']
            current_timestamp = int(terms[2])

            #compare the current against the previous
            #starting from row 2: (index 1)
            if n_rows > 1:
                #Python uses circular indices, hence: -1 means the value at the last index
                #That is, the previous time_stamp. Now perform the comparison and do something if that criterion is met:
                if current_timestamp - all_timestamp[-1] >= 0:
                    pass #the pass keyword means to do nothing. You'll have to replace it with whatever code you want

            #increment n_rows every time:
            n_rows += 1

            #always append the current timestamp to all the time_stamps
            all_timestamps.append(current_timestamp)


            if (terms[6] == ticker):
                # add something to make sure chronological order hasn't been broken
                if (allTypes == 1):
                    ofile.write(row)
            #I don't know if this was a bad indent of not, but you should know
            #where this goes
            elif (terms[0] == "A" or terms[0] == "M" or terms[0] == "D"):
                print row
                ofile.write(row)

私の最初の推測は正しかった。行を CSV コンポーネントに分割していませんでした。したがって、行で比較を行ったときに、正しい結果が得られませんでした。つまり、出力が得られませんでした。これで動作するはずです (目的に応じてわずかな変更を加えると)。:)

于 2013-10-28T02:24:29.430 に答える
0

jrd1の答えに追加するだけです。私は csv モジュールをめったに使用しません。文字列に対して分割メソッドと結合メソッドを使用するだけです。通常、私はこのようなものになります(入力と出力が1つしかない場合、通常はstdinとstdoutを使用します)。

import sys as sys

for row in sys.stdin:
  fields = row.split(",") #Could be "\t" or whatever, default is whitespace

  #process fields in someway (0 based indexing)
  fields[0] = str(int(fields[0]) + 55) 
  fields[7] = new_date_format(fields[7])
  if(some_condition_is_met):
    print(",".join(fields))

もちろん、csv ファイルが引用符や内部コンマなどを含むファンキーなエントリを取得し始めた場合、このアプローチはそれほど面白くありません。

于 2013-10-28T03:41:15.147 に答える