2012-12-03 13 views
8

Mam plik tekstowy CSV zakodowany w UTF-16 (w celu zachowania znaków Unicode, gdy inni używają Excela), ale kiedy robię read_csv z Pandą 0.9.0, otrzymuję ten tajemniczy błąd:Pandy read_csv i UTF-16

df = pd.read_csv('data.txt',encoding='utf-16',sep='\t',header=0) 
df.head() 

--------------------------------------------------------------------------- 
Exception         Traceback (most recent call last) 
<ipython-input-18-85da1383cd9e> in <module>() 
----> 1 df = pd.read_csv('candidates-spanish.txt',encoding='utf-16',sep='\t',header=0) 
    2 df.head() 

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/io/parsers.pyc in read_csv(filepath_or_buffer, sep, dialect, header, index_col, names, skiprows, na_values, keep_default_na, thousands, comment, parse_dates, keep_date_col, dayfirst, date_parser, nrows, iterator, chunksize, skip_footer, converters, verbose, delimiter, encoding, squeeze, **kwds) 
248   kdict['delimiter'] = sep 
249 
--> 250  return _read(TextParser, filepath_or_buffer, kdict) 
251 
252 @Appender(_read_table_doc) 

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/io/parsers.pyc in _read(cls, filepath_or_buffer, kwds) 
198   return parser 
199 
--> 200  return parser.get_chunk() 
201 
202 @Appender(_read_csv_doc) 

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/io/parsers.pyc in get_chunk(self, rows) 
853   elif not self._has_complex_date_col: 
854    index = self._get_simple_index(alldata, columns) 
--> 855    index = self._agg_index(index) 
856 
857   elif self._has_complex_date_col: 

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/io/parsers.pyc in _agg_index(self, index, try_parse_dates) 
980     arr, _ = _convert_types(arr, col_na_values) 
981     arrays.append(arr) 
--> 982    index = MultiIndex.from_arrays(arrays, names=self.index_name) 
983   return index 
984 

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/core/index.pyc in from_arrays(cls, arrays, sortorder, names) 
1570 
1571   return MultiIndex(levels=levels, labels=labels, 
-> 1572       sortorder=sortorder, names=names) 
1573 
1574  @classmethod 

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/core/index.pyc in __new__(cls, levels, labels, sortorder, names) 
1254   assert(len(levels) == len(labels)) 
1255   if len(levels) == 0: 
-> 1256    raise Exception('Must pass non-zero number of levels/labels') 
1257 
1258   if len(levels) == 1: 

Exception: Must pass non-zero number of levels/labels 

Odczyt danych w wiersz po wierszu z csv.reader podstawie this example zakłada, że ​​moje dane nie są nieprawidłowo sformatowane:

from io import BytesIO 
import csv 

with open('data.txt','rb') as f: 
    r = f.read().decode('utf-16').encode('utf-8') 
    for l in csv.reader(BytesIO(r),delimiter='\t'): 
     print l 

['Country', 'State/City', 'Title', 'Date', 'Catalogue', 'Wikipedia Election Page', 'Wikipedia Individual Page', 'Electoral Institution in Country', 'Twitter', 'CANDIDATE NAME 1', 'CANDIDATE NAME 2'] 
['Venezuela', 'N/A', 'President', '10/7/12', 'Hugo Rafael Chavez Frias', 'Hugo Ch\xc3\xa1vez', 'Hugo Ch\xc3\xa1vez', 'Hugo Chavez', 'Hugo Ch\xc3\xa1vez Fr\xc3\xadas', 'Hugo Chavez', 'Hugo Ch\xc3\xa1vez'] 
['Venezuela', 'N/A', 'President', '10/7/12', 'Henrique Capriles Radonski', 'Henrique Capriles Radonski', 'Henrique Capriles Radonski', 'Henrique Capriles Radonski', 'Henrique Capriles R.', 'Henrique Capriles', ''] 

Czy istnieje pewne wstępne przetwarzanie, możliwość dodawania w read_csv lub coś innego, co trzeba zrobić, zanim pandas.read_csv będzie mógł odczytać plik utf-16? Dzięki!

+0

Możesz pisać/email wersję pliku tekstowego? Spojrzę na to. –

+0

http://www.brianckeegan.com/data/candidates-spanish.txt –

Odpowiedz

8

Jest to błąd, ponieważ myślę, że czytelnik CSV mijał powrotem dodatkową pustą linię na początku. Pracował dla mnie na Python 2.7.3 i 0.9.1 pandy jeśli robię:

In [36]: pd.read_csv(BytesIO(fh.read().decode('UTF-16').encode('UTF-8')), sep='\t', header=0) 
Out[36]: 
<class 'pandas.core.frame.DataFrame'> 
Int64Index: 50 entries, 0 to 49 
Data columns: 
Country        43 non-null values 
State/City       43 non-null values 
Title        43 non-null values 
Date        43 non-null values 
Catalogue       43 non-null values 
Wikipedia Election Page    43 non-null values 
Wikipedia Individual Page   43 non-null values 
Electoral Institution in Country 43 non-null values 
Twitter        43 non-null values 
CANDIDATE NAME 1     43 non-null values 
CANDIDATE NAME 2     16 non-null values 
dtypes: object(11) 

zgłosiłem błąd tutaj: https://github.com/pydata/pandas/issues/2418 Na github opanować to niestety powoduje segfault w pozycji C-parser. Naprawimy to.

Teraz, co ciekawe: https://softwareengineering.stackexchange.com/questions/102205/should-utf-16-be-considered-harmful;)

+0

Jeśli Excel grał ładnie z UTF-8, to użyłbym tego! :) –

+1

Wszystko ustawione teraz w git master –

+0

@BrianKeegan przestań używać Excela już: p –

2
from StringIO import StringIO 
import pandas as pd 

a = ['Venezuela', 'N/A', 'President', '10/7/12', 'Hugo Rafael Chavez Frias', 'Hugo Ch\xc3\xa1vez', 'Hugo Ch\xc3\xa1vez', 'Hugo Chavez', 'Hugo Ch\xc3\xa1vez Fr\xc3\xadas', 'Hugo Chavez', 'Hugo Ch\xc3\xa1vez'] 

pd.read_csv(StringIO('\t'.join(a)), delimiter='\t') 

działa tutaj można przesłać głowę swoich danych, więc mogę przetestować

4

Python3:

with open('data.txt',encoding='UTF-16') as f: 
    df = pd.read_csv(f) 
+0

Możesz przekazać 'encoding = 'UTF-16'' bezpośrednio do' pd.read_csv() 'teraz, wtedy nie potrzebujesz' open() '. –

Powiązane problemy