Python csv string a array

187

¿Alguien sabe de una biblioteca o función simple para analizar una cadena codificada csv y convertirla en una matriz o diccionario?

No creo que quiera el módulo csv integrado porque en todos los ejemplos que he visto toma rutas de archivos, no cadenas.

Drew LeSueur
fuente

Respuestas:

259

Puede convertir una cadena en un objeto de archivo usando io.StringIOy luego pasarla al csvmódulo:

from io import StringIO
import csv

scsv = """text,with,Polish,non-Latin,letters
1,2,3,4,5,6
a,b,c,d,e,f
gęś,zółty,wąż,idzie,wąską,dróżką,
"""

f = StringIO(scsv)
reader = csv.reader(f, delimiter=',')
for row in reader:
    print('\t'.join(row))

versión más simple con split()en nuevas líneas:

reader = csv.reader(scsv.split('\n'), delimiter=',')
for row in reader:
    print('\t'.join(row))

O simplemente puede split()esta cadena en líneas usando \ncomo separador, y luego split()cada línea en valores, pero de esta manera debe tener en cuenta las comillas, por lo csvque se prefiere usar el módulo.

En Python 2 tienes que importar StringIOcomo

from StringIO import StringIO

en lugar.

Michał Niklas
fuente
66
el método de división no funcionaría si su archivo csv contuviera cadenas que contuvieran comas
Carson Myers
3
o cadenas citadas como valores (con o sin comas)
adamk el
28
Python 3 ahora usa io.StringIO. (Con suerte, ahorre un poco de tiempo a los usuarios de Python 3). importa io y io.StringIO.
JStrahl
3
En lugar de .split('\n'), puedes usar .splitlines().
Denilson Sá Maia
1
No, funciona muy bien con letras polacas con ogonki :-)
Michał Niklas
70

Simple: el módulo csv también funciona con listas:

>>> a=["1,2,3","4,5,6"]  # or a = "1,2,3\n4,5,6".split('\n')
>>> import csv
>>> x = csv.reader(a)
>>> list(x)
[['1', '2', '3'], ['4', '5', '6']]
adamk
fuente
44
Es bueno saberlo, pero tenga en cuenta que .split('\n')hará cosas extrañas si sus campos contienen nuevas líneas.
Inaimathi
1
@Inaimathi, si es csv, las nuevas líneas en el interior deberían escapar.
John La Rooy
No es necesario escapar de las nuevas líneas si se cita el campo.
Jonathan Stray
1
Esta funcionalidad no está bien documentada. Gracias.
cowlinator
13

El documento oficial de csv.reader() https://docs.python.org/2/library/csv.html es muy útil, que dice

los objetos de archivo y los objetos de lista son adecuados

import csv

text = """1,2,3
a,b,c
d,e,f"""

lines = text.splitlines()
reader = csv.reader(lines, delimiter=',')
for row in reader:
    print('\t'.join(row))
almamaquina
fuente
11
>>> a = "1,2"
>>> a
'1,2'
>>> b = a.split(",")
>>> b
['1', '2']

Para analizar un archivo CSV:

f = open(file.csv, "r")
lines = f.read().split("\n") # "\r\n" if needed

for line in lines:
    if line != "": # add other needed checks to skip titles
        cols = line.split(",")
        print cols
nvd
fuente
"¡Simple es mejor que complejo!"
Abdelouahab
9
-1 El problema con esta solución es que no tiene en cuenta el "escape de cadena", es decir, 3, "4,5,6, 6debe tratarse como tres campos en lugar de cinco.
Zz'Rot
Simple pero solo funciona en algunos casos específicos, este no es un código de análisis CSV genérico
Christophe Roussy
8

Como otros ya han señalado, Python incluye un módulo para leer y escribir archivos CSV. Funciona bastante bien siempre que los caracteres de entrada permanezcan dentro de los límites ASCII. En caso de que desee procesar otras codificaciones, se necesita más trabajo.

La documentación de Python para el módulo csv implementa una extensión de csv.reader, que usa la misma interfaz pero puede manejar otras codificaciones y devuelve cadenas unicode. Simplemente copie y pegue el código de la documentación. Después de eso, puede procesar un archivo CSV como este:

with open("some.csv", "rb") as csvFile: 
    for row in UnicodeReader(csvFile, encoding="iso-8859-15"):
        print row
roskakori
fuente
Asegúrese de que el archivo Unicode no tenga una lista de materiales (Byte Order Marker)
Pierre
1
Con respecto a la lista de materiales: Python debería detectar y omitir las listas de materiales oficiales en UTF-32, UTF-16, etc. Para saltear la lista de materiales no oficial de Microsoft para UTF-8, use 'utf-8-sig'como códec en lugar de 'utf-8'.
roskakori
7

Por la documentación:

Y aunque el módulo no admite directamente cadenas de análisis, se puede hacer fácilmente:

import csv
for row in csv.reader(['one,two,three']):
    print row

Simplemente convierta su cadena en una sola lista de elementos.

Importar StringIO me parece un poco excesivo cuando este ejemplo está explícitamente en los documentos.

roundar
fuente
2

Aquí hay una solución alternativa:

>>> import pyexcel as pe
>>> text="""1,2,3
... a,b,c
... d,e,f"""
>>> s = pe.load_from_memory('csv', text)
>>> s
Sheet Name: csv
+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
| a | b | c |
+---+---+---+
| d | e | f |
+---+---+---+
>>> s.to_array()
[[u'1', u'2', u'3'], [u'a', u'b', u'c'], [u'd', u'e', u'f']]

Aquí está la documentación.

chfw
fuente
2

Use esto para tener un csv cargado en una lista

import csv

csvfile = open(myfile, 'r')
reader = csv.reader(csvfile, delimiter='\t')
my_list = list(reader)
print my_list
>>>[['1st_line', '0'],
    ['2nd_line', '0']]
JimS
fuente
0

Panda es una biblioteca bastante potente e inteligente que lee CSV en Python

Un ejemplo simple aquí, tengo el archivo example.zip con cuatro archivos.

EXAMPLE.zip
 -- example1.csv
 -- example1.txt
 -- example2.csv
 -- example2.txt

from zipfile import ZipFile
import pandas as pd


filepath = 'EXAMPLE.zip'
file_prefix = filepath[:-4].lower()

zipfile = ZipFile(filepath)
target_file = ''.join([file_prefix, '/', file_prefix, 1 , '.csv'])

df = pd.read_csv(zipfile.open(target_file))

print(df.head()) # print first five row of csv
print(df[COL_NAME]) # fetch the col_name data

Una vez que tenga datos, puede manipularlos para jugar con una lista u otros formatos.

webbyfox
fuente