差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン次のリビジョン両方とも次のリビジョン | ||
programming:python:packages:pandas:update_multi_column [2019/06/12] – ikatakos | programming:python:packages:pandas:update_multi_column [2019/06/25] – ikatakos | ||
---|---|---|---|
行 1: | 行 1: | ||
======DataFrameの値の更新 - pandas====== | ======DataFrameの値の更新 - pandas====== | ||
- | pandasは、DataFrameへのアクセス方法がいろいろあり、お世辞にも統一的とは言えないので、よく「この書き方でいいんだっけ」と混乱する。 | + | pandasは、DataFrameへのアクセス方法がいろいろあるため、値の取得・代入もよく「この書き方でいいんだっけ」と混乱する。 |
- | 基本的には(一般的な代入と同じく)左辺で更新するデータ範囲を、右辺で値を指定するのだが、左辺でデータ範囲の指定方法が様々あるのに加え、右辺での値の指定にも複数方法がある。 | + | 基本的には(一般的な代入と同じく)左辺で更新するデータ範囲を、右辺で値を指定するのだが、左辺のデータ範囲の指定方法が様々あるのに加え、右辺での値の指定にも複数方法がある。 |
df.loc[df[' | df.loc[df[' | ||
+ | | ||
+ | col1 が 3 である行の col2,col3 列を、ともに同行の col4 の値にする | ||
大別すると以下の感じ。 | 大別すると以下の感じ。 | ||
- | 左辺のアクセス関数に例えば配列を渡しても、関数の種類や、配列の中身によって、名前か、添字か、どのように解釈されるか異なってくるのがややこしさの元となる。 | + | 左辺のアクセス関数に例えば配列を渡しても、関数の種類や配列の中身によって、名前か、添字か、どのように解釈されるか異なってくるのがややこしさの元となる。 |
* 左辺のアクセス関数 | * 左辺のアクセス関数 | ||
行 46: | 行 48: | ||
* [[http:// | * [[http:// | ||
+ | |||
+ | loc, ilocは原則 '' | ||
+ | |||
+ | 対してgetitemは、なんとなくよく使う方で解釈されるため、便利な反面、行なのか列なのか時と場合で変わり、紛らわしいので注意。 | ||
^ |^ getitem | ^ |^ getitem | ||
行 410: | 行 416: | ||
* [[https:// | * [[https:// | ||
* [[https:// | * [[https:// | ||
+ | |||
+ | |||
+ | ====小分けにする==== | ||
+ | |||
+ | 数百~数千万行のDataFrameに対して更新をかけるのは、かなりコストの重い操作となる。たとえ更新するのが一部であっても、その場所の特定に時間がかかる。 | ||
+ | |||
+ | もし、groupby() などの分割結果毎に元のDFに更新処理を行いたい場合でも、いちいち元のDFを更新していては相当時間がかかる。 | ||
+ | そもそもgroupbyごとにforループ回すのも速度的によろしいことではないが。。。関数的に書けない集計処理が必要になることもあるので仕方ない。 | ||
+ | |||
+ | そんな時、即時更新はせずリストに溜めて、更新は最後に(メモリが厳しいならある程度溜まった後に)行えば、高速化に繋がる。 | ||
+ | |||
+ | もっと速い方法もあるかも知れない。 | ||
+ | |||
+ | <sxh python> | ||
+ | # 非推奨 | ||
+ | for i, grouped_df in df.groupby(' | ||
+ | # なんか処理する | ||
+ | # 元のDFを更新する → 遅い | ||
+ | df.loc[grouped_df.index, | ||
+ | |||
+ | |||
+ | # こっちの方が速い | ||
+ | buf = [] | ||
+ | for i, grouped_df in df.groupby(' | ||
+ | # なんか処理する | ||
+ | # とりあえずバッファに溜める | ||
+ | buf.append(grouped_df[' | ||
+ | |||
+ | # 最後に更新する | ||
+ | update_sr = pd.concat(buf) | ||
+ | update_sr.sort_index(inplace=True) | ||
+ | df.loc[update_sr.index, | ||
+ | </ | ||
+ | |||