web-dev-qa-db-ja.com

Python:Pandas Series-なぜlocを使用するのですか?

なぜpandas dataframesに 'loc'を使用するのですか?locを使用または使用しない次のコードは、両方ともコンパイルとシミュレーション速度で実行されるようです。

%timeit df_user1 = df.loc[df.user_id=='5561']

100 loops, best of 3: 11.9 ms per loop

または

%timeit df_user1_noloc = df[df.user_id=='5561']

100 loops, best of 3: 12 ms per loop

なぜlocを使用するのですか?

編集:これは重複した質問としてフラグが付けられています。しかし pandas iloc vs ix vs locの説明? は言及しています*

データフレームのgetitemを使用するだけで列を取得できます。

*

df['time']    # equivalent to df.loc[:, 'time']

locを使用する理由は説明していませんが、locの多くの機能については説明していますが、私の特定の質問は「なぜlocを完全に省略しないのか」です。以下の非常に詳細な回答を受け入れました。

また、他の回答の回答(私は回答とは思わない)はディスカッションに非常に隠されており、私が探していたものを探している人は情報を見つけるのが難しく、提供された回答がはるかに役立つでしょう私の質問に。

46
Runner Bean
  • 明示的は暗黙的よりも優れています。

    df[boolean_mask]は、boolean_maskがTrueである行を選択しますが、それが望ましくない場合があります:dfにブール値の列ラベルがある場合:

    In [229]: df = pd.DataFrame({True:[1,2,3],False:[3,4,5]}); df
    Out[229]: 
       False  True 
    0      3      1
    1      4      2
    2      5      3
    

    df[[True]]を使用してTrue列を選択できます。代わりにValueErrorを発生させます:

    In [230]: df[[True]]
    ValueError: Item wrong length 1 instead of 3.
    

    locを使用した場合:

    In [231]: df.loc[[True]]
    Out[231]: 
       False  True 
    0      3      1
    

    対照的に、以下はdf2の構造が上記のdf1とほぼ同じであっても、ValueErrorを発生させません。

    In [258]: df2 = pd.DataFrame({'A':[1,2,3],'B':[3,4,5]}); df2
    Out[258]: 
       A  B
    0  1  3
    1  2  4
    2  3  5
    
    In [259]: df2[['B']]
    Out[259]: 
       B
    0  3
    1  4
    2  5
    

    したがって、df[boolean_mask]は常にdf.loc[boolean_mask]と同じ動作をするわけではありません。これはほぼ間違いなくユースケースですが、df.loc[boolean_mask]の構文の意味は明示的であるため、df[boolean_mask]の代わりに常にdf.locを使用することをお勧めします。 df.loc[indexer]を使用すると、df.locが行を選択していることが自動的にわかります。対照的に、df[indexer]ValueErrorおよびindexerに関する詳細を知らずに行または列を選択する(またはdfを上げる)かどうかは明確ではありません。

  • df.loc[row_indexer, column_index]は行を選択できますおよび列。 df[indexer]は、indexerの値のタイプとdfが持つ列のタイプに応じて、行を選択できますまたは列(再び、ブール値ですか?) 。

    In [237]: df2.loc[[True,False,True], 'B']
    Out[237]: 
    0    3
    2    5
    Name: B, dtype: int64
    
  • スライスがdf.locに渡されると、エンドポイントが範囲に含まれます。スライスがdf[...]に渡されると、スライスは半開区間として解釈されます。

    In [239]: df2.loc[1:2]
    Out[239]: 
       A  B
    1  2  4
    2  3  5
    
    In [271]: df2[1:2]
    Out[271]: 
       A  B
    1  2  4
    
47
unutbu