numpy 配列またはできれば pandas DataFrame (2D 配列の列に沿ったブロック、および - 次元配列の最も急速に変化するインデックスに沿ったブロック) で同じ値のブロックの開始インデックスと停止インデックスを見つけたいです。私は単一の次元でブロックを探すだけで、異なる行でナンを集約したくありません。
その質問 ( numpy 配列で条件を満たす多数の連続した値を見つける) から始めて、2D 配列の np.nan を見つける次のソリューションを作成しました。
import numpy as np
a = np.array([
[1, np.nan, np.nan, 2],
[np.nan, 1, np.nan, 3],
[np.nan, np.nan, np.nan, np.nan]
])
nan_mask = np.isnan(a)
start_nans_mask = np.hstack((np.resize(nan_mask[:,0],(a.shape[0],1)),
np.logical_and(np.logical_not(nan_mask[:,:-1]), nan_mask[:,1:])
))
stop_nans_mask = np.hstack((np.logical_and(nan_mask[:,:-1], np.logical_not(nan_mask[:,1:])),
np.resize(nan_mask[:,-1], (a.shape[0],1))
))
start_row_idx,start_col_idx = np.where(start_nans_mask)
stop_row_idx,stop_col_idx = np.where(stop_nans_mask)
これにより、たとえば、pd.fillna を適用する前に、欠損値のパッチの長さの分布を分析できます。
stop_col_idx - start_col_idx + 1
array([2, 1, 1, 4], dtype=int64)
もう 1 つの例と期待される結果:
a = np.array([
[1, np.nan, np.nan, 2],
[np.nan, 1, np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan]
])
array([2, 1, 2, 4], dtype=int64)
そしてそうではない
array([2, 1, 6], dtype=int64)
私の質問は次のとおりです。
- 私のソリューションを最適化する方法はありますか (マスク/where 操作の単一パスで開始と終了を見つける)?
- パンダでより最適化されたソリューションはありますか? (つまり、DataFrame の値に mask/where を適用するだけとは異なるソリューション)
- 基になる配列または DataFrame が大きすぎてメモリに収まらない場合はどうなりますか?