2012-01-18 1 views
29

私は、csvファイルからpandas.read_tableを使って構築されたパンダにデータフレームdfを持っています。データフレームには複数の列があり、列の1つでインデックス付けされています(各行はインデックス作成に使用されるその列の一意の値を持ちます)。複数の列に適用される「複雑な」フィルタ?私は簡単に列colAは、例えば10以上であるデータフレームのスライスを選択することができます。複数の列をまたがってpython pandasで選択していますか?

df_greater_than10 = df[df["colA"] > 10] 

しかし、私のようなフィルタたい場合はどのような:列のどのが大きいdfのスライスを選択します10より?

またはcolAの値が10より大きいが、colBの値が5より小さい場合は、

これらはどのようにパンダに実装されていますか?おかげさまで

答えて

36

これらの質問をmailing listに提出することをお勧めしますが、いずれにしても、それは基本的なNumPy配列で動作することはまだ非常に低いレベルです。例えば、任意の列の値は、たとえば、この例では1.5を超える行を選択する:

In [11]: df 
Out[11]: 
      A  B  C  D  
2000-01-03 -0.59885 -0.18141 -0.68828 -0.77572 
2000-01-04 0.83935 0.15993 0.95911 -1.12959 
2000-01-05 2.80215 -0.10858 -1.62114 -0.20170 
2000-01-06 0.71670 -0.26707 1.36029 1.74254 
2000-01-07 -0.45749 0.22750 0.46291 -0.58431 
2000-01-10 -0.78702 0.44006 -0.36881 -0.13884 
2000-01-11 0.79577 -0.09198 0.14119 0.02668 
2000-01-12 -0.32297 0.62332 1.93595 0.78024 
2000-01-13 1.74683 -1.57738 -0.02134 0.11596 
2000-01-14 -0.55613 0.92145 -0.22832 1.56631 
2000-01-17 -0.55233 -0.28859 -1.18190 -0.80723 
2000-01-18 0.73274 0.24387 0.88146 -0.94490 
2000-01-19 0.56644 -0.49321 1.17584 -0.17585 
2000-01-20 1.56441 0.62331 -0.26904 0.11952 
2000-01-21 0.61834 0.17463 -1.62439 0.99103 
2000-01-24 0.86378 -0.68111 -0.15788 -0.16670 
2000-01-25 -1.12230 -0.16128 1.20401 1.08945 
2000-01-26 -0.63115 0.76077 -0.92795 -2.17118 
2000-01-27 1.37620 -1.10618 -0.37411 0.73780 
2000-01-28 -1.40276 1.98372 1.47096 -1.38043 
2000-01-31 0.54769 0.44100 -0.52775 0.84497 
2000-02-01 0.12443 0.32880 -0.71361 1.31778 
2000-02-02 -0.28986 -0.63931 0.88333 -2.58943 
2000-02-03 0.54408 1.17928 -0.26795 -0.51681 
2000-02-04 -0.07068 -1.29168 -0.59877 -1.45639 
2000-02-07 -0.65483 -0.29584 -0.02722 0.31270 
2000-02-08 -0.18529 -0.18701 -0.59132 -1.15239 
2000-02-09 -2.28496 0.36352 1.11596 0.02293 
2000-02-10 0.51054 0.97249 1.74501 0.20525 
2000-02-11 0.10100 0.27722 0.65843 1.73591 

In [12]: df[(df.values > 1.5).any(1)] 
Out[12]: 
      A  B  C  D  
2000-01-05 2.8021 -0.1086 -1.62114 -0.2017 
2000-01-06 0.7167 -0.2671 1.36029 1.7425 
2000-01-12 -0.3230 0.6233 1.93595 0.7802 
2000-01-13 1.7468 -1.5774 -0.02134 0.1160 
2000-01-14 -0.5561 0.9215 -0.22832 1.5663 
2000-01-20 1.5644 0.6233 -0.26904 0.1195 
2000-01-28 -1.4028 1.9837 1.47096 -1.3804 
2000-02-10 0.5105 0.9725 1.74501 0.2052 
2000-02-11 0.1010 0.2772 0.65843 1.7359 

複数の条件は、&又は|用いて合成されなければならない(括弧を!):

In [13]: df[(df['A'] > 1) | (df['B'] < -1)] 
Out[13]: 
      A  B  C  D  
2000-01-05 2.80215 -0.1086 -1.62114 -0.2017 
2000-01-13 1.74683 -1.5774 -0.02134 0.1160 
2000-01-20 1.56441 0.6233 -0.26904 0.1195 
2000-01-27 1.37620 -1.1062 -0.37411 0.7378 
2000-02-04 -0.07068 -1.2917 -0.59877 -1.4564 

私は非常にこれらの種類のものを簡単にするいくつかの種類のクエリAPIを持っているだろう

+1

メーリングリストに今後の質問を投稿してください。しかし今のところ、プログラムでこれをやりたければどうでしょうか?あなたは列ラベルのリストを持っていました...どうすればそれを '|'表記法?例えば。 – user248237dfsf

+0

明示するには:あなたが行ったテーブルに他の値があった場合、 'any(1)'アプローチはうまくいきません。 'labels = ['A'、 'B'、 'C​​'、... 'フィルターにかけたい。多くの列があり、 'any'をそれらのサブセットに適用したいだけです(あなたはサブセットのラベルを知っています)。 – user248237dfsf

5

完全なクエリAPIを取得するまで、Pandasでこれの構文を短縮するための少なくともいくつかのアプローチがあります道路(perhap私はgithubプロジェクトに参加しようとします。これは時間の許可です。構文を少し短くする

一つの方法は以下の通りです:完全にこの問題を解決するには

inds = df.apply(lambda x: x["A"]>10 and x["B"]<5, axis=1) 
print df[inds].to_string() 

、一つは選択して句パンダへのSQLのようなものを構築する必要があります。これはまったく些細なことではありませんが、私はこのために働くかもしれない1つのスタブは、Python operator組み込みモジュールを使用することです。これにより、シンボルの代わりに関数よりも大きいものを扱うことができます。ですから、次の操作を行うことができます:

def pandas_select(dataframe, select_dict): 

    inds = dataframe.apply(lambda x: reduce(lambda v1,v2: v1 and v2, 
          [elem[0](x[key], elem[1]) 
          for key,elem in select_dict.iteritems()]), axis=1) 
    return dataframe[inds] 

次に試験例をあなたは、次の操作を行うことであろうように:

import operator 
select_dict = { 
       "A":(operator.gt,10), 
       "B":(operator.lt,5)     
       } 

print pandas_select(df, select_dict).to_string() 

をあなたはpandas_selectのに複数の引数のいずれかで構築することにより、さらに構文を短縮することができます異なる共通論理演算子を自動的に処理するか、より短い名前を持つ名前空間にそれらをインポートすることによって実行できます。

上記のpandas_select関数は、論理制約および制約のチェーンでのみ機能することに注意してください。別の論理的な振る舞いを得るには、それを変更する必要があります。またはnotとDeMorganの法則を使用してください。

+0

リスト['Alice'、 'Bob'、 'C​​arl']があれば、データフレーム['A']がリストにある項目を選択するための辞書をどのように生成できますか? –

+1

リストが 'a = ['Alice'、 'Bob'、 'C​​arl']'であり、全体のデータフレームが 'df'であれば、これを行うことができます:' df [df.A.isin(a) ] 'を呼び出すと、列Aの要素に対して設定されたメンバーシップ条件が真である行インデックスがサブ選択されます。単純な構文でこのオプションを持つように論理を表現するために私が上で行ったミニドメイン特有の言語を拡張することは、おそらく不愉快な雑用になるでしょう。 – ely

+0

おそらく今後の(pandas 0.13)クエリメソッドも参照してください: http://pandas.pydata.org/pandas-docs/dev/indexing.html?highlight=query#the-query-method-experimental またhttp ://stackoverflow.com/questions/18521037/pandas-iterative-filtering-a-dataframes-rows – RuiDC

1

この質問には質問と回答があったため、Pandasにクエリ機能が追加されました。例を以下に示します。このサンプル・データ・フレームを考える

次のようにクエリ構文

periods = 8 
dates = pd.date_range('20170101', periods=periods) 
rand_df = pd.DataFrame(np.random.randn(periods,4), index=dates, 
     columns=list('ABCD')) 

あなたはselect文の「WHERE」句のように、複数のフィルタを使用できるようになります。

rand_df.query("A < 0 or B < 0") 

は詳細についてはPandas documentationを参照してください。

関連する問題