Skip to content

Instantly share code, notes, and snippets.

@watermouth
Last active April 13, 2019 11:21
Show Gist options
  • Select an option

  • Save watermouth/8f0c8f4c6ad907ae6bbc0fe98c586064 to your computer and use it in GitHub Desktop.

Select an option

Save watermouth/8f0c8f4c6ad907ae6bbc0fe98c586064 to your computer and use it in GitHub Desktop.
pandas.DataFrame: Indexing and Selecting Data

Indexing and Selecting Data についてのメモ

ソース

http://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html

Indexing and Selecting Data

Different Choices for Indexing

  • .loc operator: 基本はlabelつまり文字列の指定を通してslicingする。整数を指定してもラベルとして用いられる。booleanや1引数のfunctionも受け付ける。
  • .iloc operator: 基本は整数値を指定してslicingする。
  • [] operator: 一応使えることになってはいるが、推奨ではないのでは???

Indexer

多軸を持つオブジェクトに対するindexingによるデータ取得は、実質的に各軸すべてに対してindexingを行う必要がある。 何も書かない軸はすべてを対象としていることになり、null sliceである:を指定していることになる。

Object Type Indexers
Series s.loc[indexer]
DataFrame df.loc[row_indexer,column_indexer]
Panel p.loc[item_indexer,major_indexer,minor_indexer]

chained assignment, is_copy property

  • ひとつのindexingで代入する。data[1][3] = "hoge"みたいなのはchained assignmentになってwarningがでる。 そしてdata.iloc[1,3]の値は更新されない...いつコピーが発生したのか...
  • 次のようなものも結局複数回indexingして設定しているのでchained assignmentになる
x = data[:5]
x[3] = "fuga"

でwarningが出る。

  • 仕様確認のためのサンプルコード

  • 初期設定

x = pd.DataFrame(columns=["A","B"], data=np.transpose(np.array([[1,2,3],[4,5,6]])))
y = x[:2]
print(x)
print(y)
print(x.is_copy is not None, y.is_copy is not None)
print("x[:1][:2]", x[:1][:2])
print("x[:2][:3]", x[:2][:3])
print("x[:3][:2]", x[:3][:2])
print("x[:3][:3]", x[:3][:3])```

- 2段階のslicingで設定してみる  

x[:3][1:2] = 100 print("x", x.is_copy, x[:3].is_copy, x[:3][2:3].is_copy, "\n", x)

これはxに100をセットできる。slicingによるアクセスであるためコピーされたデータフレームへのセットにならないようだ。

- 2段階目を個別要素指定にしてみる  

x[:3][2] = 200 print("x", x.is_copy, x[:3].is_copy, "\n", x)

これはxは変化せずwarningが出る。x[:3]がコピーされたデータフレームを返しており、
その2番目(厳密には(2,:))の要素に200をセットする処理になる。xは変化しない。

- ilocを使って設定してみる  

x.iloc[0,0] = 10 print("x",x) print("y",y)

x,yの変化を確認できる。素直に参照として扱っているので両方とも変化していることを確認できる。

- xのslicingであるyに対してilocで値を設定してみる  

y.iloc[0,1] = 99 print("x", x) print("y", y)

これはwarningが出る。値はx,yの両方とも更新される。  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment