2013-08-27 91 views
6

Tôi có một tệp được phân tách bằng tab có cột nên được hiểu là chuỗi, nhưng nhiều mục nhập là số nguyên. Với các tập tin nhỏ read_csv giải thích một cách chính xác các cột như là một chuỗi sau khi nhìn thấy một số giá trị số nguyên không, nhưng với các tập tin lớn hơn, điều này không làm việc:pandas read_csv vấn đề suy luận dtype

import pandas as pd 
df = pd.DataFrame({'a':['1']*100000 + ['X']*100000 + ['1']*100000, 'b':['b']*300000}) 
df.to_csv('test', sep='\t', index=False, na_rep='NA') 
df2 = pd.read_csv('test', sep='\t') 
print df2['a'].unique() 
for a in df2['a'][262140:262150]: 
    print repr(a) 

đầu ra:

['1' 'X' 1] 
'1' 
'1' 
'1' 
'1' 
1 
1 
1 
1 
1 
1 

Điều thú vị là 262.144 là một sức mạnh của 2 vì vậy tôi nghĩ suy luận và chuyển đổi đang diễn ra theo từng phần nhưng bỏ qua một số đoạn.

Tôi khá chắc chắn đây là lỗi, nhưng muốn một công việc xung quanh có thể sử dụng trích dẫn, mặc dù thêm quoting = csv.QUOTE_NONNUMERIC để đọc và viết không khắc phục được sự cố. Lý tưởng nhất là tôi có thể giải quyết vấn đề này bằng cách trích dẫn dữ liệu chuỗi của tôi và bằng cách nào đó buộc gấu trúc không thực hiện bất kỳ suy luận nào về dữ liệu được trích dẫn.

Sử dụng gấu trúc 0.12.0

+2

[tài liệu] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.io.parsers.read_csv.html) làm cho nó trông như thế này sẽ hoạt động: 'pd.read_csv (' test ', sep =' \ t ', bộ chuyển đổi = {' a ': str}) '. –

+0

@StevenRumbalski và nó hoàn toàn không! Bạn nên thêm câu trả lời này làm câu trả lời! –

+0

@AndyHayden: Cảm ơn - đã xong. –

Trả lời

5

Bạn đã bị lừa phân tích cú pháp read_csv ở đây (và phải công bằng, tôi không nghĩ rằng nó có thể luôn được dự kiến ​​sẽ ra một cách chính xác không có vấn đề gì bạn ném vào nó) ... nhưng có, nó có thể là a bug!

Như @Steven chỉ ra bạn có thể dùng tham số chuyển đổi của read_csv:

df2 = pd.read_csv('test', sep='\t', converters={'a': str}) 

Một giải pháp lười biếng chỉ là để vá này lên sau khi bạn đã đọc trong file:

In [11]: df2['a'] = df2['a'].astype('str') 

# now they are equal 
In [12]: pd.util.testing.assert_frame_equal(df, df2) 

Lưu ý: Nếu bạn đang tìm kiếm một giải pháp để lưu trữ DataFrames, ví dụ: giữa các phiên, cả hai phần mềm và HDF5Store là các giải pháp tuyệt vời sẽ không bị ảnh hưởng bởi các loại lỗi phân tích cú pháp này (và sẽ nhanh hơn đáng kể). Xem: How to store data frame using PANDAS, Python

+0

đây là dự phòng của tôi nhưng liên quan đến các dòng mã bổ sung mỗi khi tôi đọc một tệp mà tôi đang cố gắng tránh giải pháp – andrew

+0

có thể không sử dụng to_csv/read_csv để lưu trữ cho bạn DataFrames, to_pickle hoặc hdf5_store là giải pháp tốt hơn nhiều (và sẽ không bị ảnh hưởng bởi loại lỗi phân tích cú pháp này). –

+0

@ user1068490 được cập nhật với liên kết đến câu trả lời khác về giải pháp đó –

6

Để tránh việc Pandas suy ra kiểu dữ liệu của bạn, cung cấp một cuộc tranh luận converters-read_csv:

converters: dict. tùy chọn

Nguyên tắc chức năng để chuyển đổi giá trị trong các cột nhất định. Phím có thể là số nguyên hoặc nhãn cột

Đối với tập tin của bạn này sẽ như thế nào:

df2 = pd.read_csv('test', sep='\t', converters={'a':str}) 

đọc của tôi về các tài liệu là bạn không cần phải xác định chuyển đổi cho mỗi cột. Pandas nên tiếp tục suy ra kiểu dữ liệu của các cột không xác định.

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