artículos lista dentro leídos Re-formato de archivo CSV en Python
Pregunta
Tengo algunas líneas en un archivo CSV como esto:
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
Si te fijas, algunos números están encerrados en "" y tiene un separador de miles "". Quiero quitar el separador de miles y el recinto comillas dobles. Para el cerramiento qoute, estoy pensando en usar String.Replace (), pero ¿qué hay de la coma dentro de las comillas?
¿Cuál es la mejor manera de hacer esto en Python?
Solución
Simplemente podría analizar el CSV, hacer los cambios necesarios y luego escribir de nuevo.
(no he probado este código, sino que debe ser algo como esto)
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)
Otros consejos
Aquí hay un poco de expresión regular tocar el violín que va a hacer el truco:
>>> 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'
Elimina las comas de las partes de la cadena que es entre pares de comillas.
Si lo que quieres es eliminar comillas y comas de una cadena, un par de reemplaza lo hará:
s = s.replace('"','').replace(',','')
Una forma más rápida es utilizar s.translate
, pero que requiere un mínimo de preparación:
import string
identity = string.maketrans('', '')
...
s = s.translate(identity, '",')
Esto elimina cualquier ocurrencia de dobles comillas o comas, y lo hace bastante rápido también. En general, el método .translate
de objetos de cadena es la mejor manera de eliminar ciertos tipos de caracteres de una cadena (así como, posiblemente, realizar alguna traducción caracteres a caracteres, pero, mediante el uso de un traducen tabla como la identity
uno muestro aquí, la parte de la traducción puede de hecho ser evitada fácilmente). Tenga en cuenta que .translate
funciona un poco diferente para los objetos Unicode (y por lo tanto para Python 3 cuerdas, también) -. Estoy dando el enfoque que es conveniente para Python 2 objetos de cadena sin formato
Aquí hay algo Acabo de prueba, puede que no necesite pprint, sólo quiero utilizar para la salida clara.
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
Código, lector de uso csv, y pasar cada elemento para la función parseNum para comprobar dígito o no válida.
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)
salida
[[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']]
Nota: Si necesita una buena precisión en números flotantes, reemplace flotador con decimal
Utilice la href="http://docs.python.org/library/csv.html" rel="nofollow noreferrer"> csv módulo
Debe utilizar absolutamente el módulo csv
. Si utiliza un csv.reader
, sólo tiene uno muy pequeño problema: las pruebas campos para ver si son números, comas y pelar si lo son. He empaquetado como un generador:
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
Uso:
>>> 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']