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.

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.


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']]

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))

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

"¡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

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.



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.


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']]

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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.