再フォーマットリスト内の項目は、PythonでCSVファイルから読み込みます
質問
私はこのようなCSVファイル内のいくつかの行を持っています
1000001234,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2
あなたが気付いた場合は、、いくつかの数字は、「「で囲まれた」と桁区切りを持っている」されています。私は千個の区切りと二重引用符のエンクロージャを削除したいです。 qouteエンクロージャのために、私は引用符内のカンマについてstring.replace()が、どのように使用するのではと思っています?
Pythonでこれを行うための最善の方法は何ですか?
解決
あなたは単に、CSVを解析し、必要な変更を行い、その後、再びそれを書くことができます。
(私はこのコードをテストしていませんが、それはこのようなものでなければなりません)。
import csv
reader = csv.reader(open('IN.csv', 'r'))
writer = csv.writer(open('OUT.csv', 'w')
for row in reader:
# do stuff to the row here
# row is just a list of items
writer.writerow(row)
他のヒント
ここでトリックを行います正規表現いじるのビットがあります:
>>> import re
>>> p = re.compile('["]([^"]*)["]')
>>> x = """1000001234,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2"""
>>> p.sub(lambda m: m.groups()[0].replace(',',''), x)
'1000001234,Account Name,0,0,3711.32,0,0,18629.64,22340.96,COD,20000.00,Some string,Some string 2'
引用符対の間にある文字列の部分からカンマを削除します。
あなたが望むすべての文字列から、二重引用符とカンマを削除する場合は、置き換えのカップルはそれを行います。
s = s.replace('"','').replace(',','')
より高速な方法はs.translate
を使用することですが、それは準備の最小値を必要とします:
import string
identity = string.maketrans('', '')
...
s = s.translate(identity, '",')
この二重引用符またはカンマのいずれかの発生を削除し、それはかなり速いすぎません。一般的には、文字列オブジェクトの.translate
方法は、そのような私が示す1 identity
としてテーブルを変換し使用することにより、おそらくいくつかの文字に文字変換を実行するだけでなく、(文字列から、特定の種類を削除するための最良の方法ですが、ここでは、翻訳部分は、実際には簡単に)にバイパスすることができます。 (あまりにも、したがって、Pythonの3つの文字列のために)その.translate
がUnicodeオブジェクトのために少し異なる動作します - 私は無地のPython 2文字列オブジェクトに適していますアプローチを与えている。
ここでは、私はちょうどテストしたものです、私はちょうど明確な出力に使用したい、PPRINTを必要としないことがあります。
のtest.CSV
1000001234,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2
1000001234,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2
コード、使用CSVリーダー、及び有効数字かどうかを確認するparseNum関数に各項目を渡す。
from pprint import pprint
import csv
def parseNum(x):
xx=x.replace(",","")
if not xx.replace(".","").isdigit(): return x
return "." in xx and float(xx) or int(xx)
x=[map(parseNum,line) for line in csv.reader(open("test.csv"))]
pprint(x)
出力
[[1000001234,
'Account Name',
0,
0,
3711.3200000000002,
0,
0,
18629.639999999999,
22340.959999999999,
'COD',
20000.0,
'Some string',
'Some string 2'],
[1000001234,
'Account Name',
0,
0,
3711.3200000000002,
0,
0,
18629.639999999999,
22340.959999999999,
'COD',
20000.0,
'Some string',
'Some string 2']]
注:浮動小数点数に良い精度が必要な場合は、交換するのフロートの<のhref = "http://docs.python.org/library/decimal.html" のrel = "nofollowをnoreferrerと「>小数点の
CSV のモジュールを使用してください。それはあなたが作業しているファイルの種類について他の区切り文字、引用符、およびすべての設定を支援するための定数やパラメータのすべての種類があります。それも、あなたがファイルのCSV形式を識別するのに役立つことができスニファを持っています。実際には、これは適切かつ簡単にCSVファイルを扱うことができ、私が見つけた唯一のモジュールです。
あなたは絶対csv
モジュールを使用する必要があります。彼らはしている場合、彼らは数字をしているかどうかを確認するためのテストフィールド、およびストリッピングカンマ:あなたはcsv.reader
を使用する場合は、あなただけの1つの非常に小さな問題を抱えています。私は発電機としてそれをパッケージ化しました。
import csv
def read_and_fix_numbers(f):
"""Iterate over a file object that returns CSV data, stripping commas out of numbers."""
for row in csv.reader(f):
for field in row:
try:
x = float(field)
field.replace(",", "")
except ValueError:
pass
fixed.append(field)
yield fixed
使用方法:
>>> data = '1000001234,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2'
>>> import StringIO
>>> f = StringIO.StringIO(data)
>>> for row in read_and_fix_numbers(f):
print row
['1000001234', 'Account Name', '0', '0', '3711.32', '0', '0', '18629.64', '22340.96', 'COD', '20000.00', 'Some string', 'Some string 2']