LoginSignup
6
1

More than 5 years have passed since last update.

Pandas DataFrame の [] (__getitem__) にリストを与えたときの挙動

Last updated at Posted at 2018-07-01

Pandas の DataFrame には苦手意識がある。あまりにインターフェイスが複雑すぎてわけがわからない。特に一番複雑なのは [](__getitem__) 。ドキュメントがまともにない。

やはり同じようなことを考えていた人が stack overflow にいた。

Pandas DataFrame: complete spec for __getitem__()?

結局、ソースコードを読め、ということらしい。普通に Python で書いてあるので読めることは読める。frame.py というファイルに書いてある。私が一番気になるのは、 __getitem__ にリストを与えたときの挙動だ。__getitem__ から呼び出されている次のメソッドに答えがあった(pandas のバージョンは 0.22.0)。

    def _getitem_array(self, key):
        # also raises Exception if object array with NA values
        if com.is_bool_indexer(key):
            # warning here just in case -- previously __setitem__ was
            # reindexing but __getitem__ was not; it seems more reasonable to
            # go with the __setitem__ behavior since that is more consistent
            # with all other indexing behavior
            if isinstance(key, Series) and not key.index.equals(self.index):
                warnings.warn("Boolean Series key will be reindexed to match "
                              "DataFrame index.", UserWarning, stacklevel=3)
            elif len(key) != len(self.index):
                raise ValueError('Item wrong length %d instead of %d.' %
                                 (len(key), len(self.index)))
            # check_bool_indexer will throw exception if Series key cannot
            # be reindexed to match DataFrame rows
            key = check_bool_indexer(self.index, key)
            indexer = key.nonzero()[0]
            return self._take(indexer, axis=0, convert=False)
        else:
            indexer = self.loc._convert_to_indexer(key, axis=1)
            return self._take(indexer, axis=1, convert=True)

com.is_bool_indexer(key) で key が bool(真偽値)かどうかチェックしているのが味噌。
要するに、

  • bool なら、行のセレクタ
  • bool 以外なら、列のセレクタ

として動作しているということだ。

だから、

df[df.x == 1]

なら、「カラムx が 1 である行を抜き出して DataFrame として返す」し、

df[['x']]

なら、「カラムxだけを抜き出して DataFrame として返す」という動作になる。

同じようなことは、loc を使ってもできるので、動作が曖昧な __getitem__ はあまり使わないほうがいいのかもしれない。ただ、簡潔に書けるのは魅力的なので、用量を守って使用すればいいのかな。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1