pandasのDataFrameのlocインデクサは行、列の順で絞り込む(例:df.loc[df["b"]>12, "a"]) (original) (raw)
はじめに
いくおです。 nikkieです。
Today(※最近) I learned です。
目次
動作環境
% uv version uv 0.4.27 (Homebrew 2024-10-25) % uv run --python 3.12 --with pandas python
- Python 3.12.5
import pandas as pd pd.version '2.2.3'
[]
を2回使って行と列を指定するも、そこに代入できていない
DataFrameを作ります
df = pd.DataFrame({"a": [11, 21, 31], "b": [12, 22, 32], "c": [13, 23, 33]}) df a b c 0 11 12 13 1 21 22 23 2 31 32 33
b列が12より大きい行(すなわち、インデックスが1と2の行)を取り出すと
df[df["b"]>12] a b c 1 21 22 23 2 31 32 33
そのa列は
df[df["b"]>12]["a"] 1 21 2 31 Name: a, dtype: int64
以上から、b列が12より大きい行のa列の値を書き換えようとすると
df[df["b"]>12]["a"] = 99 :1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html
例外が送出されたわけではないですが、df
は変わっていません(df
のコピーでだけa列の値が変わったのかな?)
df a b c 0 11 12 13 1 21 22 23 2 31 32 33
locを使ってアクセス・代入してみる
警告で案内された.loc[row_indexer,col_indexer]
を試します1。
今回理解したのは、**.loc[行を絞る,列を絞る]
** ということです。
b列が12より大きい行
df.loc[df["b"]>12] a b c 1 21 22 23 2 31 32 33
b列が12より大きい行のa列
df.loc[df["b"]>12, "a"] 1 21 2 31 Name: a, dtype: int64
書き換えられます!!
df.loc[df["b"]>12, "a"] = 99 df a b c 0 11 12 13 1 99 22 23 2 99 32 33
『pandasクックブック』にあたる
古い本ですが、手元の『pandasクックブック』よりdf.loc[rows, columns]
という書式について
カンマの左側の選択は、行インデックスによる行選択、カンマの右側は常にカラムインデックスによるカラム選択だ。(p.79)
またクックブックでは、
df[]
をインデックス演算子df.loc[]
を.loc
インデクサ
と呼んでいました (p.73)
終わりに
pandasのDataFrameでloc
インデクサは行->列の順で絞れる(df.loc[rows, columns]
)ことを理解しました。
今回の例では、df["b"]>12
で行を絞り、それらの列を"a"
で指定しました。
インデックス演算子で指定して値を代入したところ元が書き換わりませんでしたが、loc
インデクサを使うと書き換えられました!
pandasを知ってからloc
インデクサは自分のものにできていない感じでしたが、今回で完全に理解しました!