Python stringa CSV per l'array


187

Qualcuno sa di una semplice libreria o funzione per analizzare una stringa codificata CSV e trasformarla in un array o in un dizionario?

Non credo di volere il modulo csv integrato perché in tutti gli esempi che ho visto prende percorsi di file, non stringhe.

Risposte:


259

Puoi convertire una stringa in un oggetto file usando io.StringIOe quindi passarla al csvmodulo:

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

versione più semplice con split()su newline:

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

Oppure puoi semplicemente split()trasformare questa stringa in righe usando \ncome separatore, e poi split()ogni riga in valori, ma in questo modo devi essere consapevole delle virgolette, quindi csvè preferibile usare il modulo.

Su Python 2 devi importare StringIOcome

from StringIO import StringIO

anziché.


6
il metodo split non funzionerebbe se il suo file CSV contenesse stringhe contenenti virgole
Carson Myers,

3
o stringhe tra virgolette come valori (con o senza virgole)
adamk,

28
Python 3 ora utilizza io.StringIO. (Speriamo di salvare un po 'di tempo gli utenti di Python 3). quindi importare io e io.StringIO.
JStrahl,

3
Invece di .split('\n'), puoi usare .splitlines().
Denilson Sá Maia,

1
No, funziona molto bene con le lettere polacche con ogonki :-)
Michał Niklas

70

Semplice: anche il modulo CSV funziona con le liste:

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

4
Buono a sapersi, ma tieni presente che .split('\n')farà cose strane se i tuoi campi contengono nuove righe.
Inaimathi,

1
@Inaimathi, Se è CSV, le nuove righe all'interno dovrebbero essere sfuggite.
John La Rooy,

Le newline non devono essere salvate se il campo è quotato.
Jonathan Stray,

1
Questa funzionalità non è ben documentata. Grazie.
cowlinator

13

Il documento ufficiale per csv.reader() https://docs.python.org/2/library/csv.html è molto utile, che dice

oggetti file e oggetti elenco sono entrambi adatti

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

Per analizzare un file 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

"Semplice è meglio che complesso!"
Abdelouahab,

9
-1 Il problema di questa soluzione è che non tiene conto di "stringa fuga", cioè 3, "4,5,6, 6sono considerati come tre campi invece di cinque.
Zz'Rot

Semplice ma funziona solo in alcuni casi specifici, questo non è un codice di analisi CSV generico
Christophe Roussy,

8

Come altri hanno già sottolineato, Python include un modulo per leggere e scrivere file CSV. Funziona abbastanza bene fintanto che i caratteri di input rimangono entro i limiti ASCII. Nel caso in cui si desideri elaborare altre codifiche, è necessario ulteriore lavoro.

La documentazione di Python per il modulo CSV implementa un'estensione di CSV.reader, che utilizza la stessa interfaccia ma può gestire altre codifiche e restituire stringhe unicode. Basta copiare e incollare il codice dalla documentazione. Successivamente, puoi elaborare un file CSV come questo:

with open("some.csv", "rb") as csvFile: 
    for row in UnicodeReader(csvFile, encoding="iso-8859-15"):
        print row

Assicurati che il file Unicode non abbia una DBA (indicatore ordine byte)
Pierre,

1
Per quanto riguarda la distinta base: Python dovrebbe rilevare e saltare le distinte base ufficiali in UTF-32, UTF-16 ecc. Per saltare la distinta non ufficiale di Microsoft per UTF-8, utilizzare 'utf-8-sig'come codec anziché 'utf-8'.
Roskakori,

7

Per la documentazione:

E mentre il modulo non supporta direttamente le stringhe di analisi, può essere facilmente eseguito:

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

Trasforma la tua stringa in un unico elenco di elementi.

L'importazione di StringIO mi sembra un po 'eccessiva quando questo esempio è esplicitamente nei documenti.



2

Ecco una soluzione 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']]

Ecco la documentazione


2

Usalo per caricare un CSV in un elenco

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 è una libreria abbastanza potente e intelligente che legge CSV in Python

Un semplice esempio qui, ho file example.zip con quattro file al suo interno.

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 volta che hai i dati puoi manipolarli per giocare con un elenco o altri formati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.