差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン最新のリビジョン両方とも次のリビジョン | ||
programming:python:packages:pandas:update_multi_column [2019/06/26] – ikatakos | programming:python:packages:pandas:update_multi_column [2021/12/03] – [巨大なDFに対する更新はなるべく一度に] ikatakos | ||
---|---|---|---|
行 413: | 行 413: | ||
数百~数千万行のDataFrameに対して更新をかけるのは、かなりコストの重い操作となる。たとえ更新する範囲が一部であっても、その場所の特定に時間がかかる。 | 数百~数千万行のDataFrameに対して更新をかけるのは、かなりコストの重い操作となる。たとえ更新する範囲が一部であっても、その場所の特定に時間がかかる。 | ||
- | もし、groupby() などの分割結果毎に何らかの集計処理し、元のDFに結果を反映させたい場合でも、毎回、元のDFを更新していては相当時間がかかる。 | + | もし、groupby() などの分割結果毎に何らかの集計処理し、元のDFに結果を反映させたい場合でも、毎回、元のDFを更新していては相当時間がかかる。\\ |
- | (そもそもgroupbyごとにforループ回すのも速度的によろしいことではないが。。。関数的に書けない集計処理が必要になることもあるので仕方ない) | + | (そもそもgroupbyごとにforループ回すのも速度的によろしいことではないが。。。関数的に書けない処理が必要になることもあるので仕方ない) |
そんな時、即時更新はせずリストに溜めて、更新は最後に(メモリが厳しいならある程度溜まった後に)行えば、高速化に繋がる。 | そんな時、即時更新はせずリストに溜めて、更新は最後に(メモリが厳しいならある程度溜まった後に)行えば、高速化に繋がる。 | ||
- | 下記は一例だが、もっと速い方法もあるかも知れない。 | + | 下記は一例だが、もっと速い方法もあるかも知れない。(例なので処理内容には特に意味は無い) |
- | <sxh python> | + | <sxh python; |
- | # 非推奨 | + | # ' |
for i, grouped_df in df.groupby(' | for i, grouped_df in df.groupby(' | ||
# なんか処理する | # なんか処理する | ||
- | # 元のDFを更新する → 遅い | + | # 毎回、元のDFを更新する → 遅い |
- | df.loc[grouped_df.index, | + | df.loc[grouped_df.index, |
+ | </ | ||
- | + | <sxh python; | |
- | # こっちの方が速い | + | # ' |
buf = [] | buf = [] | ||
for i, grouped_df in df.groupby(' | for i, grouped_df in df.groupby(' | ||
# なんか処理する | # なんか処理する | ||
# とりあえずバッファに溜める | # とりあえずバッファに溜める | ||
- | buf.append(grouped_df[' | + | buf.append(grouped_df[' |
# 最後に更新する | # 最後に更新する | ||
- | update_sr = pd.concat(buf) | + | update_sr = pd.concat(buf) |
update_sr.sort_index(inplace=True) | update_sr.sort_index(inplace=True) | ||
df.loc[update_sr.index, | df.loc[update_sr.index, | ||
+ | </ | ||
+ | |||
+ | <sxh python; | ||
+ | # ' | ||
+ | |||
+ | update_data = [] | ||
+ | update_indices = [] | ||
+ | for i, grouped_df in df.groupby(' | ||
+ | # なんか処理する | ||
+ | | ||
+ | # 更新用numpy配列を作る | ||
+ | n = len(grouped_df) | ||
+ | si = grouped_df.index[0] | ||
+ | ti = grouped_df.index[-1] | ||
+ | | ||
+ | update_table = np.zeros((n, | ||
+ | update_table[:, | ||
+ | update_table[:, | ||
+ | | ||
+ | # 蓄積する | ||
+ | update_data.append(update_table) | ||
+ | update_indices.extend(range(si, | ||
+ | |||
+ | # 最後に更新する | ||
+ | update_table = np.concatenate(update_data, | ||
+ | df.loc[update_indices, | ||
</ | </ | ||