pandas read_csv 및 usecols로 열 필터링


98

여러 인덱스로 pandas.read_csv열을 필터링 usecols하고 사용할 때 올바르게 들어오지 않는 csv 파일이 있습니다.

import pandas as pd
csv = r"""dummy,date,loc,x
   bar,20090101,a,1
   bar,20090102,a,3
   bar,20090103,a,5
   bar,20090101,b,1
   bar,20090102,b,3
   bar,20090103,b,5"""

f = open('foo.csv', 'w')
f.write(csv)
f.close()

df1 = pd.read_csv('foo.csv',
        header=0,
        names=["dummy", "date", "loc", "x"], 
        index_col=["date", "loc"], 
        usecols=["dummy", "date", "loc", "x"],
        parse_dates=["date"])
print df1

# Ignore the dummy columns
df2 = pd.read_csv('foo.csv', 
        index_col=["date", "loc"], 
        usecols=["date", "loc", "x"], # <----------- Changed
        parse_dates=["date"],
        header=0,
        names=["dummy", "date", "loc", "x"])
print df2

df1과 df2는 누락 된 더미 열을 제외하고는 동일해야하지만 열에 레이블이 잘못 지정되어 있어야합니다. 또한 날짜는 날짜로 구문 분석됩니다.

In [118]: %run test.py
               dummy  x
date       loc
2009-01-01 a     bar  1
2009-01-02 a     bar  3
2009-01-03 a     bar  5
2009-01-01 b     bar  1
2009-01-02 b     bar  3
2009-01-03 b     bar  5
              date
date loc
a    1    20090101
     3    20090102
     5    20090103
b    1    20090101
     3    20090102
     5    20090103

이름 대신 열 번호를 사용하면 동일한 문제가 발생합니다. read_csv 단계 후에 더미 열을 삭제하여 문제를 해결할 수 있지만 무엇이 잘못되었는지 이해하려고합니다. pandas 0.10.1을 사용하고 있습니다.

편집 : 잘못된 헤더 사용 수정.


1
다른 것, headernames키워드 의 사용법이 올바르지 않습니다 (이 때문에 첫 번째 행이 예제에서 누락되었습니다. header헤더가있는 행으로 int (기본값 0)을 예상합니다. 1로 해석되는 'True'를 제공하기 때문에, 두 번째 행 (첫 번째 데이터 행)이 헤더로 사용되고 누락되었습니다. 그러나 열 이름은 names인수로 덮어 쓰기 때문에 정확합니다 . 그러나 기본적으로 두 행을 그대로두고 첫 번째 행이 열 이름으로 사용됩니다. 그러나, 초기 문제가 해결되지 않습니다.
요리스

1
이것은 usecols버그 처럼 보입니다 . 버그 2654 와 관련이 있습니까?
abudis 2013

버그는 이름과 헤더 인수없이 여전히 존재합니다.
Andy Hayden

@andy 조금 더 찌르고 팬더 버그에 제출하겠습니다. 온 전성 검사에 감사드립니다.

답변:


115

@chip의 대답은 두 개의 키워드 인수의 요점을 완전히 놓쳤습니다.

  • 이름 은 헤더가없고 정수 인덱스가 아닌 열 이름을 사용하여 다른 인수를 지정하려는 경우에만 필요합니다.
  • usecols 는 전체 DataFrame을 메모리로 읽기 전에 필터를 제공해야합니다. 제대로 사용하면 읽은 후 열을 삭제할 필요가 없습니다.

이 솔루션은 이러한 이상한 점을 수정합니다.

import pandas as pd
from StringIO import StringIO

csv = r"""dummy,date,loc,x
bar,20090101,a,1
bar,20090102,a,3
bar,20090103,a,5
bar,20090101,b,1
bar,20090102,b,3
bar,20090103,b,5"""

df = pd.read_csv(StringIO(csv),
        header=0,
        index_col=["date", "loc"], 
        usecols=["date", "loc", "x"],
        parse_dates=["date"])

이는 우리에게 다음을 제공합니다.

                x
date       loc
2009-01-01 a    1
2009-01-02 a    3
2009-01-03 a    5
2009-01-01 b    1
2009-01-02 b    3
2009-01-03 b    5

1
이것은 CSV 데이터를 구문 분석하는 교과서 솔루션이지만, 당시에 는 실제 데이터에 헤더가 없기 때문에 names 인수 를 사용하려고했습니다 .

2
이 경우 header=0. 당신은 사용 싶어 header=None하고 사용할 names뿐만 아니라.
Mack

하지만 여전히 usecols@Mack을 유지하려는 열에 정수 인덱스와 함께 사용 합니까?
Mr_and_Mrs_D

22

이 코드는 당신이 원하는 것을 달성합니다 --- 또한 ​​이상하고 확실히 버그가 있습니다.

다음과 같은 경우에 작동한다는 것을 관찰했습니다.

a) 상대를 지정합니다 index_col. 실제로 사용하는 열 수에 따라-이 예에서는 4 개가 아닌 3 개 열 ( dummy그때부터 삭제 하고 계산을 시작합니다)

b) 동일 parse_dates

c) 그렇지 않다 usecols;) 명백한 이유로

d) 여기서 나는 names이 행동을 반영 하도록 조정했습니다.

import pandas as pd
from StringIO import StringIO

csv = """dummy,date,loc,x
bar,20090101,a,1
bar,20090102,a,3
bar,20090103,a,5
bar,20090101,b,1
bar,20090102,b,3
bar,20090103,b,5
"""

df = pd.read_csv(StringIO(csv),
        index_col=[0,1],
        usecols=[1,2,3], 
        parse_dates=[0],
        header=0,
        names=["date", "loc", "", "x"])

print df

어느 인쇄

                x
date       loc   
2009-01-01 a    1
2009-01-02 a    3
2009-01-03 a    5
2009-01-01 b    1
2009-01-02 b    3
2009-01-03 b    5

1
감사. 데이터가 올바로 들어 왔기 때문에과 names숫자 를 다시 정렬하는 올바른 조합을 찾지 못했습니다 usecols.

8

csv 파일에 추가 데이터가 포함 경우 가져온 후 DataFrame에서 열을 삭제할 수 있습니다 .

import pandas as pd
from StringIO import StringIO

csv = r"""dummy,date,loc,x
bar,20090101,a,1
bar,20090102,a,3
bar,20090103,a,5
bar,20090101,b,1
bar,20090102,b,3
bar,20090103,b,5"""

df = pd.read_csv(StringIO(csv),
        index_col=["date", "loc"], 
        usecols=["dummy", "date", "loc", "x"],
        parse_dates=["date"],
        header=0,
        names=["dummy", "date", "loc", "x"])
del df['dummy']

이는 우리에게 다음을 제공합니다.

                x
date       loc
2009-01-01 a    1
2009-01-02 a    3
2009-01-03 a    5
2009-01-01 b    1
2009-01-02 b    3
2009-01-03 b    5

내 경우 index_col이 문제를 일으키는 이유는 제안한 것처럼 열 이름을 사용하려고 시도했지만 열 번호를 전달하면 해결되었습니다.
YouAreAwesome

4
그러나 이것은 자원의 낭비입니다
Mr_and_Mrs_D

1

index_col=False매개 변수 만 추가하면 됩니다.

df1 = pd.read_csv('foo.csv',
     header=0,
     index_col=False,
     names=["dummy", "date", "loc", "x"], 
     index_col=["date", "loc"], 
     usecols=["dummy", "date", "loc", "x"],
     parse_dates=["date"])
  print df1

-4

먼저 csv를 가져오고 csv.DictReader를 사용하여 처리하기 쉽습니다.


2
이것은 더 쉬울 수 있지만 상당히 느립니다. 대용량 데이터 세트를 작업 할 때 (저는 현재 단일 13GB CSV 파일로 작업하고 있습니다) 파일이로드 될 때까지 몇 시간을 기다릴 필요가없는 것이 훨씬 더 중요합니다.
가짜 이름
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.