leer - python csv writer example
Lectura de archivos CSV en numpy donde el delimitador es "," (1)
El problema básico es que NumPy no entiende el concepto de pelar citas (mientras que el módulo csv
hace). Cuando dices delimiter=''","''
, le estás diciendo a NumPy que el delimitador de columna es literalmente una coma citada, es decir, las comillas están alrededor de la coma, no el valor, por lo que las comillas adicionales que obtienes la primera y la última columna son esperados.
Al mirar los documentos de función, creo que tendrá que configurar el parámetro de converters
para quitarle las comillas (el valor predeterminado no):
import re
import numpy as np
fieldFilter = re.compile(r''^"?([^"]*)"?$'')
def filterTheField(s):
m = fieldFilter.match(s.strip())
if m:
return float(m.group(1))
else:
return 0.0 # or whatever default
#...
# Yes, sorry, you have to know the number of columns, since the NumPy docs
# don''t say you can specify a default converter for all columns.
convs = dict((col, filterTheField) for col in range(numColumns))
data = np.genfromtxt(csvfile, dtype=None, delimiter='','', names=True,
converters=convs)
O abandone np.genfromtxt()
y deje que csv.csvreader
proporcione los contenidos del archivo una fila a la vez, como listas de cadenas, y luego simplemente itere a través de los elementos y cree la matriz:
reader = csv.csvreader(csvfile)
result = np.array([[float(col) for col in row] for row in reader])
# BTW, column headings are in reader.fieldnames at this point.
EDITAR: De acuerdo, parece que su archivo no es flotante. En ese caso, puede establecer convs
según sea necesario en el caso genfromtxt
o crear un vector de funciones de conversión en el caso csv.csvreader
:
reader = csv.csvreader(csvfile)
converters = [datetime, float, int, float]
result = np.array([[conv(col) for col, conv in zip(row, converters)]
for row in reader])
# BTW, column headings are in reader.fieldnames at this point.
EDIT 2: Bien, conteo de columna variable ... Su fuente de datos solo quiere dificultar la vida. Afortunadamente, podemos usar magic
...
reader = csv.csvreader(csvfile)
result = np.array([[magic(col) for col in row] for row in reader])
... donde la magic()
es solo un nombre que obtuve de la cima de una función. (¡Psique!)
En el peor, podría ser algo así como:
def magic(s):
if ''/'' in s:
return datetime(s)
elif ''.'' in s:
return float(s)
else:
return int(s)
Tal vez NumPy tiene una función que toma una cadena y devuelve un solo elemento con el tipo correcto. numpy.fromstring()
parece estar cerca, pero podría interpretar el espacio en sus marcas de tiempo como un separador de columnas.
La desventaja de PS One con csvreader
que veo es que no descarta los comentarios; los archivos csv
reales no tienen comentarios.
Tengo un archivo CSV con un formato que se ve así:
"FieldName1", "FieldName2", "FieldName3", "FieldName4"
"13/04/2010 14: 45: 07.008", "7.59484916392", "10", "6.552373"
"13/04/2010 14: 45: 22.010", "6.55478493312", "9", "3.5378543"
...
Tenga en cuenta que hay caracteres de comillas dobles al principio y al final de cada línea en el archivo CSV, y la cadena ","
se usa para delimitar campos dentro de cada línea. La cantidad de campos en el archivo CSV puede variar de un archivo a otro.
Cuando trato de leer esto en numpy a través de:
import numpy as np
data = np.genfromtxt(csvfile, dtype=None, delimiter='','', names=True)
todos los datos se leen como valores de cadena, rodeados de caracteres de comillas dobles. No es irracional, pero no me sirve mucho porque luego tengo que volver y convertir cada columna en su tipo correcto
Cuando uso delimiter=''","''
lugar, todo funciona como me gustaría, a excepción del primer y el último campo. Como el inicio de los caracteres de línea y fin de línea es un carácter de comillas dobles, no se ve como un delimitador válido para los campos primero y último, por lo que se leen como, por ejemplo, "04/13/2010 14:45:07.008
y 6.552373"
- tenga en cuenta los caracteres de comillas dobles "04/13/2010 14:45:07.008
y 6.552373"
respectivamente. Debido a estos caracteres redundantes, numpy supone que el primer y el último campo son ambos tipos de cadena; No quiero que sea el caso
¿Hay alguna forma de instruir a numpy para leer en archivos formateados de esta manera como me gustaría, sin tener que volver atrás y "arreglar" la estructura de la matriz numpy después de la lectura inicial?