差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
次のリビジョン両方とも次のリビジョン
programming:python:packages:pandas:update_multi_column [2019/06/13] ikatakosprogramming:python:packages:pandas:update_multi_column [2019/06/26] – [巨大なDFに対する更新はなるべく一度に] ikatakos
行 1: 行 1:
 ======DataFrameの値の更新 - pandas====== ======DataFrameの値の更新 - pandas======
  
-pandasは、DataFrameアクセス方法がいろいろあるため、値の取得・代入もよく「この書き方でいいんだっけ」と混乱する。+pandasは、DataFrameの値の取得方法がいろいろあるため、値の代入更新つい「この書き方でいいんだっけ」と混乱する。
  
 基本的には(一般的な代入と同じく)左辺で更新するデータ範囲を、右辺で値を指定するのだが、左辺のデータ範囲の指定方法が様々あるのに加え、右辺での値の指定にも複数方法がある。 基本的には(一般的な代入と同じく)左辺で更新するデータ範囲を、右辺で値を指定するのだが、左辺のデータ範囲の指定方法が様々あるのに加え、右辺での値の指定にも複数方法がある。
行 20: 行 20:
     * 名前の配列、添字の配列     * 名前の配列、添字の配列
     * 名前のslice、添字のslice     * 名前のslice、添字のslice
-    * 列数と同じ長さのbool配列 +    * 列数と同じ長さのbool配列行数と同じ長さのbool配列
-    * 行数と同じ長さのbool配列+
     * DataFrame     * DataFrame
     * Series     * Series
行 28: 行 27:
     * 左辺と同じサイズの配列     * 左辺と同じサイズの配列
  
-ここで、「名前」とは行や列に付けられた名称を差し、「添字」とは0から始まる連番(通常の配列の要素取得に使うもの)を指すものとする。+ここで、「名前」とは行や列に付けられた名称を差し、「添字」とは0から始まる連番(通常の配列の要素取得に使うもの)を指すものとする。
  
-''print(df)'' した時は、名前は表示されるが、添字は表示されない。 +配列は numpy.ndarray でもよい。
-また、添字は負の値で末尾から数えられるなど、通常の配列の添字と似た機能を持つ。 +
- +
-                          1      2    ←列の添字 +
-                  col1   col2   col3    ←列の名前 +
-  0  2019/01/01 +
-  1  2019/01/08 +
-  2  2019/01/15 +
-  ↑         ↑ +
-  行の添字 行の名前 +
- +
-配列は numpy.ndarray でもよい。+
  
 ====範囲の指定方法==== ====範囲の指定方法====
行 49: 行 37:
   * [[http://sinhrks.hatenablog.com/entry/2014/11/12/233216|Python pandas データ選択処理をちょっと詳しく <前編> - StatsFragments]]   * [[http://sinhrks.hatenablog.com/entry/2014/11/12/233216|Python pandas データ選択処理をちょっと詳しく <前編> - StatsFragments]]
  
-loc, ilocは原則 ''[行, 列]'' の順でlocが名前、ilocが添字として解釈されるため意味を明確にコーディングしたい場合はそちらを使うのが良い。+loc, ilocは法則性がありわかりやすい。原則 ''loc[行, 列]'' の順で指定する。(bool配列以外は)locが名前、ilocが添字として解釈される。 
 +意味を明確にコーディングしたい場合はこれらを使うのが良い。
  
-対してgetitemは、なんとなくよく使う方で解釈されるため、便利な反面、行なのか列なのか時と場合で変わり、紛らわしいので注意+対してgetitemは、なんとなくよく使う方で解釈されるため、便利な反面、行なのか列なのか時と場合で変わり、やや紛らわしい。
  
 ^                                                                  |^  getitem                                                        ^  loc                                              ^  iloc                                         ^ ^                                                                  |^  getitem                                                        ^  loc                                              ^  iloc                                         ^
行 389: 行 378:
  
 但し、あるidに条件を満たすレコードが1つも無かった場合、そのidのカラムcはnanになる。 但し、あるidに条件を満たすレコードが1つも無かった場合、そのidのカラムcはnanになる。
 +
 +=====その他小ネタ=====
  
 ====inplaceは効かない==== ====inplaceは効かない====
行 416: 行 407:
   * [[https://stackoverflow.com/questions/43856701/pandas-inplace-view-copy-confusion|python - Pandas - inplace, view, copy confusion - Stack Overflow]]   * [[https://stackoverflow.com/questions/43856701/pandas-inplace-view-copy-confusion|python - Pandas - inplace, view, copy confusion - Stack Overflow]]
   * [[https://github.com/pandas-dev/pandas/issues/11984|Pandas replacing values on specific columns. view vs. copy · Issue #11984 · pandas-dev/pandas · GitHub]]   * [[https://github.com/pandas-dev/pandas/issues/11984|Pandas replacing values on specific columns. view vs. copy · Issue #11984 · pandas-dev/pandas · GitHub]]
 +
 +
 +====巨大なDFに対する更新はなるべく一度に====
 +
 +数百~数千万行のDataFrameに対して更新をかけるのは、かなりコストの重い操作となる。たとえ更新する範囲が一部であっても、その場所の特定に時間がかかる。
 +
 +もし、groupby() などの分割結果毎に何らかの集計処理し、元のDFに結果を反映させたい場合でも、毎回、元のDFを更新していては相当時間がかかる。
 +(そもそもgroupbyごとにforループ回すのも速度的によろしいことではないが。。。関数的に書けない集計処理が必要になることもあるので仕方ない)
 +
 +そんな時、即時更新はせずリストに溜めて、更新は最後に(メモリが厳しいならある程度溜まった後に)行えば、高速化に繋がる。
 +
 +下記は一例だが、もっと速い方法もあるかも知れない。
 +
 +<sxh python>
 +# 非推奨
 +for i, grouped_df in df.groupby('AAA'):
 +    # なんか処理する
 +    # 毎回、元のDFを更新する → 遅い
 +    df.loc[grouped_df.index, 'BBB'] = grouped_df['CCC']
 +
 +
 +# こっちの方が速い
 +buf = []
 +for i, grouped_df in df.groupby('AAA'):
 +    # なんか処理する
 +    # とりあえずバッファに溜める
 +    buf.append(grouped_df['CCC'])
 +
 +# 最後に更新する
 +update_sr = pd.concat(buf)
 +update_sr.sort_index(inplace=True)  # indexは整列されてた方が速い
 +df.loc[update_sr.index, 'BBB'] = update_sr
 +</sxh>
 +
  
  
programming/python/packages/pandas/update_multi_column.txt · 最終更新: 2021/12/03 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0