2015-01-30 32 views
5

Tôi có csvs lớn, nơi tôi chỉ quan tâm đến một tập con của các hàng. Đặc biệt, tôi muốn đọc trong tất cả các hàng xảy ra trước khi một điều kiện cụ thể được đáp ứng.đọc có điều kiện hàng của csv trong gấu trúc

Ví dụ, nếu read_csv sẽ mang lại dataframe:

 A B  C 
1 34 3.20 'b' 
2 24 9.21 'b' 
3 34 3.32 'c' 
4 24 24.3 'c' 
5 35 1.12 'a' 
... 
1e9 42 2.15 'd' 

là có một số cách để đọc tất cả các hàng trong csv cho đến khi col B vượt quá 10. Trong ví dụ trên, tôi muốn đọc trong:

 A B  C 
1 34 3.20 'b' 
2 24 9.21 'b' 
3 34 3.32 'c' 
4 24 24.3 'c' 

tôi biết làm thế nào để ném những hàng này ra sau khi đã đọc dataframe trong, nhưng vào thời điểm này tôi đã dành tất cả những gì tính toán đọc chúng trong tôi không có quyền truy cập vào các chỉ số. của hàng cuối cùng trước khi đọc csv (no skipfooter)

+1

Tôi không nghĩ có một cách đơn giản để làm điều này trong API Pandas. Có thể bạn sẽ phải thoát ra khỏi 'csv', lấy từng hàng một, đặt chúng vào danh sách các danh sách, dừng lại khi bạn nhận được hàng cuối cùng mà bạn muốn, và sau đó xây dựng một' DataFrame' ra khỏi danh sách kết quả của danh sách. –

+1

Bạn có thể đọc csv theo khối và chỉ nối thêm nếu tập hợp con đáp ứng điều kiện của bạn – EdChum

Trả lời

12

Bạn có thể đọc csv theo khối. Vì pd.read_csv sẽ trả về một trình lặp khi thông số chunksize được chỉ định, bạn có thể sử dụng itertools.takewhile để chỉ đọc nhiều phần theo nhu cầu của mình mà không cần đọc toàn bộ tệp.

import itertools as IT 
import pandas as pd 

chunksize = 10 ** 5 
chunks = pd.read_csv(filename, chunksize=chunksize, header=None) 
chunks = IT.takewhile(lambda chunk: chunk['B'].iloc[-1] < 10, chunks) 
df = pd.concat(chunks) 
mask = df['B'] < 10 
df = df.loc[mask] 

Hoặc, để tránh phải sử dụng df.loc[mask] để loại bỏ hàng không mong muốn từ đoạn cuối cùng, có lẽ là một giải pháp sạch sẽ được xác định một máy phát điện tùy chỉnh:

import itertools as IT 
import pandas as pd 

def valid(chunks): 
    for chunk in chunks: 
     mask = chunk['B'] < 10 
     if mask.all(): 
      yield chunk 
     else: 
      yield chunk.loc[mask] 
      break 

chunksize = 10 ** 5 
chunks = pd.read_csv(filename, chunksize=chunksize, header=None) 
df = pd.concat(valid(chunks)) 
+0

@DSM: Bạn có nghĩa là 'chunk.ix [-1, 'B']'? – unutbu

+0

@DSM: Cảm ơn, bạn đã đúng. Ngay cả 'chunk.ix [-1, 'B']' sẽ trả về giá trị sai nếu chỉ mục 'chunk' bao gồm -1 là một giá trị. – unutbu

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