Python csv string to array

187

Czy ktoś zna prostą bibliotekę lub funkcję do analizowania ciągu zakodowanego w formacie CSV i przekształcania go w tablicę lub słownik?

Nie sądzę, żebym chciał mieć wbudowany moduł csv, ponieważ we wszystkich przykładach, które widziałem, pobiera ścieżki plików, a nie ciągi.

Drew LeSueur
źródło

Odpowiedzi:

259

Możesz przekonwertować ciąg znaków na obiekt pliku za pomocą, io.StringIOa następnie przekazać go do csvmodułu:

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

prostsza wersja z split()nowymi liniami:

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

Lub możesz po prostu split()umieścić ten ciąg w wierszach, używając \njako separatora, a następnie split()każdy wiersz w wartości, ale w ten sposób musisz być świadomy cudzysłowów, więc csvpreferowane jest użycie module.

W Pythonie 2 musisz importować StringIOjako

from StringIO import StringIO

zamiast.

Michał Niklas
źródło
6
metoda podziału nie działałaby, gdyby jego plik csv zawierał ciągi znaków zawierające przecinki
Carson Myers,
3
lub cytowane łańcuchy jako wartości (z przecinkami lub bez)
adamk
28
Python 3 używa teraz io.StringIO. (Mam nadzieję, że zaoszczędzisz trochę czasu użytkownikom Pythona 3). więc zaimportuj io i io.StringIO.
JStrahl,
3
Zamiast tego .split('\n')możesz użyć .splitlines().
Denilson Sá Maia
1
Nie, działa bardzo dobrze z polskimi literami z ogonkami :-)
Michał Niklas
70

Proste - moduł csv działa również z listami:

>>> 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
źródło
4
Dobrze wiedzieć, ale pamiętaj, że .split('\n')będzie to robić dziwne rzeczy, jeśli twoje pola zawierają znaki nowej linii.
Inaimathi
1
@Inaimathi, jeśli jest to csv, znaki nowej linii w środku powinny zostać zmienione.
John La Rooy,
Znaków nowych linii nie trzeba używać, jeśli pole jest cytowane.
Jonathan Stray
1
Ta funkcja nie jest dobrze udokumentowana. Dziękuję Ci.
cowlinator
13

Bardzo pomocny jest oficjalny dokument dotyczący csv.reader() https://docs.python.org/2/library/csv.html , który mówi

obiekty plików i obiekty listy są odpowiednie

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))
soulmachine
źródło
11
>>> a = "1,2"
>>> a
'1,2'
>>> b = a.split(",")
>>> b
['1', '2']

Aby przeanalizować plik 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
źródło
„Proste jest lepsze niż złożone!”
Abdelouahab
9
-1 Problem z tym rozwiązaniem polega na tym, że nie bierze ono pod uwagę „ucieczki ciągów”, tzn. 3, "4,5,6, 6Będzie traktowane jako trzy pola zamiast pięciu.
Zz'Rot
Prosty, ale działa tylko w określonych przypadkach, nie jest to ogólny kod parsowania CSV
Christophe Roussy
8

Jak inni już zauważyli, Python zawiera moduł do odczytu i zapisu plików CSV. Działa całkiem dobrze, o ile znaki wejściowe mieszczą się w granicach ASCII. Jeśli chcesz przetworzyć inne kodowania, potrzeba więcej pracy.

Dokumentacja Pythona dotycząca modułu csv implementuje rozszerzenie csv.reader, które używa tego samego interfejsu, ale może obsługiwać inne kodowania i zwraca ciągi znaków Unicode. Wystarczy skopiować i wkleić kod z dokumentacji. Następnie możesz przetworzyć plik CSV w następujący sposób:

with open("some.csv", "rb") as csvFile: 
    for row in UnicodeReader(csvFile, encoding="iso-8859-15"):
        print row
roskakori
źródło
Upewnij się, że plik Unicode nie ma BOM (znacznik kolejności bajtów)
Pierre
1
Odnośnie BOM: Python powinien wykrywać i pomijać oficjalne BOM w UTF-32, UTF-16 itp. Aby pominąć nieoficjalne BOM Microsoft dla UTF-8, użyj 'utf-8-sig'jako kodeka zamiast 'utf-8'.
roskakori
7

Zgodnie z dokumentacją:

I chociaż moduł nie obsługuje bezpośrednio analizowania ciągów, można to łatwo zrobić:

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

Po prostu zamień swój ciąg w listę pojedynczego elementu.

Importowanie StringIO wydaje mi się nieco przesadne, gdy ten przykład jest jawnie w dokumentacji.

okrągły
źródło
2

Oto alternatywne rozwiązanie:

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

Oto dokumentacja

chfw
źródło
2

Użyj tego, aby załadować plik csv do listy

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
źródło
0

Panda to dość potężna i sprytna biblioteka odczytująca CSV w Pythonie

Prosty przykład, mam plik example.zip z czterema plikami.

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

Gdy masz już dane, możesz manipulować nimi, aby grać z listą lub innymi formatami.

webbyfox
źródło