Làm cách nào để lọc các dòng khi tải trong hàm Pandas read_csv?


95

Làm cách nào để lọc các dòng CSV sẽ được tải vào bộ nhớ bằng cách sử dụng gấu trúc? Đây có vẻ như là một lựa chọn mà người ta nên tìm read_csv. Tui bỏ lỡ điều gì vậy?

Ví dụ: chúng tôi có một CSV với cột dấu thời gian và chúng tôi chỉ muốn tải những dòng có dấu thời gian lớn hơn một hằng số nhất định.

Câu trả lời:


165

Không có tùy chọn để lọc các hàng trước khi tệp CSV được tải vào đối tượng gấu trúc.

Bạn có thể tải tệp và sau đó lọc bằng cách sử dụng df[df['field'] > constant], hoặc nếu bạn có một tệp rất lớn và bạn lo lắng về việc hết bộ nhớ, thì hãy sử dụng trình lặp và áp dụng bộ lọc khi bạn nối các phần của tệp, ví dụ:

import pandas as pd
iter_csv = pd.read_csv('file.csv', iterator=True, chunksize=1000)
df = pd.concat([chunk[chunk['field'] > constant] for chunk in iter_csv])

Bạn có thể thay đổi tùy chọn chunksizecho phù hợp với bộ nhớ hiện có của mình. Xem tại đây để biết thêm chi tiết.


cho chunk['filed']>constanttôi có thể kẹp nó giữa 2 giá trị không đổi không? Ví dụ: hằng1> chunk ['trường']> hằng2. Hoặc tôi có thể sử dụng 'trong phạm vi'?
frofwefwqg3

1
Hãy thử:chunk[(chunk['field'] > constant2)&(chunk['field']<constant1)]
Johannes Wachs

Cái này thiếu a .loc? chunk.loc[chunk['field'] > constant]
Vincent

1
Bạn có thể sử dụng mặt nạ boolean có hoặc không .loc. Tôi không nghĩ rằng nó .locđã tồn tại vào năm 2012, nhưng tôi đoán những ngày này việc sử dụng .locnó rõ ràng hơn một chút.
Matti John

8

Tôi đã không tìm thấy một cách dễ dàng để làm điều đó trong bối cảnh của read_csv. Tuy nhiên, read_csvtrả về một DataFrame, có thể được lọc bằng cách chọn các hàng theo vectơ boolean df[bool_vec]:

filtered = df[(df['timestamp'] > targettime)]

Đây là việc chọn tất cả các hàng trong df (giả sử df là bất kỳ DataFrame nào, chẳng hạn như kết quả của read_csvcuộc gọi, ít nhất chứa một cột datetime timestamp) mà các giá trị trong timestampcột này lớn hơn giá trị của targettime. Câu hỏi tương tự .


1
Tôi không chắc về điều này, nhưng tôi có cảm giác rằng việc sử dụng bộ nhớ sẽ cực kỳ nặng nề.
Nathan

2

Nếu phạm vi được lọc gần nhau (như thường xảy ra với các bộ lọc thời gian (tem)), thì giải pháp nhanh nhất là mã hóa phạm vi hàng. Đơn giản chỉ cần kết hợp skiprows=range(1, start_row)với nrows=end_rowcác tham số. Sau đó, quá trình nhập sẽ mất vài giây trong khi giải pháp được chấp nhận sẽ mất vài phút. Một vài thử nghiệm với ban đầu start_rowkhông phải là chi phí lớn do tiết kiệm được thời gian nhập khẩu. Lưu ý rằng chúng tôi đã giữ hàng tiêu đề bằng cách sử dụng range(1,..).


-3

Nếu bạn đang sử dụng Linux, bạn có thể sử dụng grep.

# to import either on Python2 or Python3
import pandas as pd
from time import time # not needed just for timing
try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO


def zgrep_data(f, string):
    '''grep multiple items f is filepath, string is what you are filtering for'''

    grep = 'grep' # change to zgrep for gzipped files
    print('{} for {} from {}'.format(grep,string,f))
    start_time = time()
    if string == '':
        out = subprocess.check_output([grep, string, f])
        grep_data = StringIO(out)
        data = pd.read_csv(grep_data, sep=',', header=0)

    else:
        # read only the first row to get the columns. May need to change depending on 
        # how the data is stored
        columns = pd.read_csv(f, sep=',', nrows=1, header=None).values.tolist()[0]    

        out = subprocess.check_output([grep, string, f])
        grep_data = StringIO(out)

        data = pd.read_csv(grep_data, sep=',', names=columns, header=None)

    print('{} finished for {} - {} seconds'.format(grep,f,time()-start_time))
    return data

1
Sử dụng grep là một lựa chọn tồi vì một số lý do. 1) nó là chậm 2) nó không phải cầm tay 3) nó không phải là gấu trúc hoặc python (bạn có thể sử dụng biểu thức thông thường ngay trong python) đó là lý do tôi downvoted câu trả lời của bạn
Ahmed Masud

Giải pháp của bạn không hoạt động trên tất cả các nền tảng và nó cũng bao gồm Grep. Đây là lý do cho sự giảm giá trị.
Roman Orac

-3

Bạn có thể chỉ định nrowstham số.

import pandas as pd df = pd.read_csv('file.csv', nrows=100)

Mã này hoạt động tốt trong phiên bản 0.20.3.


1
OP đang hỏi làm thế nào để lọc không giới hạn số dòng được đọc. Đây là lý do tại sao tôi từ chối câu trả lời của bạn.
Roman Orac
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.