2015-10-07 14 views
8

Tôi có tệp CSV mà tôi đã tải xuống từ trang web của WHO (http://apps.who.int/gho/data/view.main.52160, Tài nguyên đã tải xuống, "bảng đa năng ở định dạng CSV"). Tôi cố gắng để tải các tập tin vào một mảng numpy. Dưới đây là mã của tôi:Đang tải tệp UTF-8 bằng Python 3 bằng cách sử dụng numpy.genfromtxt

import numpy 
#U75 - unicode string of max. length 75 
world_alcohol = numpy.genfromtxt("xmart.csv", dtype="U75", skip_header=2, delimiter=",") 
print(world_alcohol) 

Và tôi nhận

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2: ordinal not in range(128).

Tôi đoán NumPy rằng có một vấn đề đọc chuỗi "Côte d'Ivoire". Tệp được mã hóa đúng UTF-8 (theo trình soạn thảo văn bản của tôi). Tôi đang sử dụng Python 3.4.3 và gumpy 1.9.2.

Tôi đang làm gì sai? Làm thế nào tôi có thể đọc các tập tin vào numpy?

Trả lời

8

Trong Python3 tôi có thể làm:

In [224]: txt = "Côte d'Ivoire" 
In [225]: x = np.zeros((2,),dtype='U20') 
In [226]: x[0] = txt 
In [227]: x 
Out[227]: 
array(["Côte d'Ivoire", ''], dtype='<U20') 

Có nghĩa là tôi có lẽ có thể mở tập tin một 'UTF-8' (thường xuyên, không phải chế độ byte), và readlines, và gán chúng với các yếu tố của một mảng như x.

Nhưng genfromtxt nhấn mạnh vào hoạt động với chuỗi byte (ascii) không thể xử lý tập hợp UTF-8 lớn hơn (7 byte v 8). Vì vậy, tôi cần phải áp dụng decode tại một số thời điểm để có được một mảng U.

tôi có thể tải nó thành một mảng 'S' với genfromtxt:

In [258]: txt="Côte d'Ivoire" 
In [259]: a=np.genfromtxt([txt.encode()],delimiter=',',dtype='S20') 
In [260]: a 
Out[260]: 
array(b"C\xc3\xb4te d'Ivoire", dtype='|S20') 

và áp dụng decode đến các yếu tố cá nhân:

In [261]: print(a.item().decode()) 
Côte d'Ivoire 

In [325]: print _ 
Côte d'Ivoire 

Hoặc sử dụng np.char.decode để áp dụng nó vào mỗi phần tử của một mảng :

In [263]: np.char.decode(a) 
Out[263]: 
array("Côte d'Ivoire", dtype='<U13') 
In [264]: print(_) 
Côte d'Ivoire 

genfromtxt để s tôi chỉ định converters:

In [297]: np.genfromtxt([txt.encode()],delimiter=',',dtype='U20', 
    converters={0:lambda x: x.decode()}) 
Out[297]: 
array("Côte d'Ivoire", dtype='<U20') 

Nếu csv có một kết hợp của chuỗi và số, cách tiếp cận converters này sẽ dễ dàng hơn để sử dụng hơn so với np.char.decode. Chỉ cần chỉ định trình biến đổi cho mỗi cột chuỗi.

(Xem các chỉnh sửa trước đó của tôi cho Python2 thử).

+0

Không OP nhưng cảm ơn vì sự tích lũy rõ ràng và hữu ích của câu trả lời. – KobeJohn

+1

Cảm ơn bạn đã trả lời. Nó hoạt động! Tôi chỉ mới bắt đầu với Python và tôi thấy nó kỳ quặc đến mức không thể đọc được UTF-8 out-of-the-box. Tôi đã đọc rằng Python là dễ dàng và phát triển với sự đơn giản và dễ sử dụng trong tâm trí chưa đọc UTF-8 đòi hỏi phải hội tụ bổ sung? Tôi nghĩ chúng ta đang sống vào năm 2015. – JustAC0der

Các vấn đề liên quan