パンダのread_csvとusecolsを使用した列のフィルター


97

複数のインデックスを使用し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ステップの後にダミー列を削除することで問題を回避できますが、何が問題なのかを理解しようとしています。私はパンダ0.10.1を使用しています。

編集:不正なヘッダーの使用法を修正しました。


1
それ以外の場合、headerおよびnamesキーワードの使用法が正しくありません(これが、例の最初の行が欠落してheaderいる理由です。ヘッダーのある行としてint(デフォルトは0)が必要です。1と解釈される 'True'を指定したため、 2行目(最初のデータ行)はヘッダーとして使用されており、欠落しています。ただし、names引数で上書きするため、列名は正しいです。ただし、両方をそのままにして、最初の行をデフォルトで列名に使用することもできます。しかし、それはあなたの最初の質問は解決しません。
ヨリス

1
これはusecolsバグのようです。おそらくバグ2654に関連していますか?
アブディス2013

名前とヘッダー引数がないバグはまだ残っています。
アンディヘイデン

@andy私はもう少しつついて、パンダのバグに投稿します。健全性チェックに感謝します。
チップ

回答:


113

@chipによる答えは、2つのキーワード引数の要点を完全に逃しています。

  • 名前は、ヘッダーがなく、整数インデックスではなく列名を使用して他の引数を指定する場合にのみ必要です。
  • 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データを解析するための教科書ソリューションですが、実際のデータにはヘッダーがなかったため、私は名前引数を使用することに専念していました。
チップ

2
その場合、は指定しませんheader=0。使いたいしheader=None、さらに使いたいnames
Mack

しかし、それでもusecols@Mackを保持したい列の整数インデックスで使用しますか?
Mr_and_Mrs_D 2018

22

このコードはあなたが望むものを実現します---その奇妙で確かにバグがあります:

私はそれが機能することを観察しました:

a)index_colrel を指定します。実際に使用する列の数に-つまり、この例では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

0

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
これは簡単かもしれませんが、非常に遅いです。大きなデータセットで作業しているとき(私は現在、自分で13 GBの単一のCSVファイルを使用しています)、ファイルが読み込まれるまで何時間も待つ必要がないことが非常に重要になります。
偽の名前
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.