どういうこと?
例えば、こんなデータフレームの NaN にランダムな別々の値を入れたい。
import pandas as pd
import numpy as np
df = pd.DataFrame({'a': [1, 2, np.nan, 4],
'b': [np.nan, 3, np.nan, np.nan]})
| a | b | |
|---|---|---|
| 0 | 1.0 | NaN |
| 1 | 2.0 | 3.0 |
| 2 | NaN | NaN |
| 3 | 4.0 | NaN |
いまのところ pandas.DataFrame.fillna では実現できない。
実際、 pandas.DataFrame.fillna— pandas 0.25.1 documentation には以下のとおり記載されている。
value : scalar, dict, Series, or DataFrame
Value to use to fill holes (e.g. 0), alternately a dict/Series/DataFrame of values specifying which value to use for each index (for a Series) or column (for a DataFrame). Values not in the dict/Series/DataFrame will not be filled. This value cannot be a list.
どうする?
pandas.DataFrame.mask を使う。
引数の other に元のデータフレームと同じ shape のランダムな array を指定する。
df.mask(df.isna(), other=np.random.rand(*df.shape))
結果の一例
| a | b | |
|---|---|---|
| 0 | 1.0 | 0.017323 |
| 1 | 2.0 | 3.0 |
| 2 | 0.071862 | 0.455177 |
| 3 | 4.0 | 0.527770 |
いくつかの選択肢からランダムな値を入れたいのであれば choice で生成する。
df.mask(df.isna(), np.random.choice(['a', 'b', 'c'], df.shape))
結果の一例
| a | b | |
|---|---|---|
| 0 | 1 | b |
| 1 | 2 | 3 |
| 2 | b | a |
| 3 | 4 | a |