Pandas read_csv 함수에서로드시 줄을 어떻게 필터링 할 수 있습니까?


95

Pandas를 사용하여 메모리에로드 할 CSV 줄을 어떻게 필터링 할 수 있습니까? 이것은에서 찾아야 할 옵션처럼 보입니다 read_csv. 내가 뭔가를 놓치고 있습니까?

예 : 타임 스탬프 열이있는 CSV가 있고 주어진 상수보다 큰 타임 스탬프가있는 행만로드하려고합니다.

답변:


165

CSV 파일이 pandas 객체에로드되기 전에 행을 필터링하는 옵션은 없습니다.

파일을로드 한 다음를 사용하여 필터링 df[df['field'] > constant]하거나, 매우 큰 파일이 있고 메모리 부족이 걱정되는 경우 반복자를 사용하고 파일 청크를 연결할 때 필터를 적용 할 수 있습니다. 예 :

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])

당신은 다를 수 chunksize사용 가능한 메모리를 이용할 수 있습니다. 자세한 내용은 여기 를 참조하십시오.


에 chunk['filed']>constant나는이 개 상수 값 사이를 끼워 할 수 있습니까? 예 : 상수 1> 청크 [ '필드']> 상수 2. 아니면 '범위 내'를 사용할 수 있습니까?
— weefwefwqg3

1
시도 :chunk[(chunk['field'] > constant2)&(chunk['field']<constant1)]
— Johannes Wachs

이것이 누락 .loc되었습니까? chunk.loc[chunk['field'] > constant]
— Vincent

1
부울 마스크를 사용하거나 사용하지 않고 사용할 수 있습니다 .loc. 나는 .loc2012 년에 존재 했다고 생각하지 않지만 요즘 사용하는 .loc것이 좀 더 명시 적이라고 생각합니다 .
— Matti John

8

의 컨텍스트 내에서 직접 수행하는 방법을 찾지 못했습니다 read_csv. 그러나 read_csv부울 벡터로 행을 선택하여 필터링 할 수있는 DataFrame을 반환합니다 df[bool_vec].

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

이것은 열의 값이 targettime 의 값 보다 큰 df의 모든 행을 선택하는 것입니다 (df가 read_csv적어도 datetime 열을 포함하는 호출 결과와 같은 DataFrame이라고 가정 timestamp) timestamp. 비슷한 질문 입니다.


1
나는 이것에 대해 확실하지 않지만 이것이 메모리 사용량에 극도로 무거울 것이라고 생각합니다.
— Nathan

2

필터링 된 범위가 연속적인 경우 (일반적으로 시간 (스탬프) 필터와 함께) 가장 빠른 솔루션은 행 범위를 하드 코딩하는 것입니다. 매개 변수 skiprows=range(1, start_row)와 결합 하기 만하면 nrows=end_row됩니다. 그런 다음 가져 오기에는 몇 초가 걸리며 수락 된 솔루션에는 몇 분이 걸립니다. 초기에 대한 몇 가지 실험 start_row은 수입 시간이 절약된다는 점을 감안할 때 큰 비용이 아닙니다. 를 사용하여 헤더 행을 유지했습니다 range(1,..).


-3

nrows매개 변수 를 지정할 수 있습니다 .

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

이 코드는 버전 0.20.3에서 잘 작동합니다.


1
OP는 읽는 줄 수를 제한하지 않고 필터링하는 방법을 묻습니다. 이것이 내가 당신의 대답을 반대 한 이유입니다.
— 로마 ORAC

-4

Linux를 사용하는 경우 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
grep을 사용하는 것은 여러 가지 이유로 심각하게 나쁜 선택입니다. 1)는 느린 2) 휴대용 아니라 그렇지 않은 3) 팬더 또는 파이썬 (정규 표현식 바로 내부 파이썬을 사용할 수 있습니다) 나는 당신의 대답을 downvoted 이유는
— 아메드 마수드를

솔루션이 모든 플랫폼에서 작동하는 것은 아니며 Grep도 포함됩니다. 이것이 반대표의 이유입니다.
— Roman Orac 19.07.04
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.