大熊猫。根据变量分布替换NAN值

时间:2016-11-19 18:11:00

标签: python pandas dataframe null

考虑到分布,我需要替换列中的nan值。该值的归一化频率为0.5879336282383848,0.37367433995536975和0.03839203180624546。 我打算做点什么:

for idx in nan_cols:
    if random() < 0.03839203180624546:
         df[idx][col] = 0
    elif random() < 0.03839203180624546 + 0.37367433995536975:
         df[idx][col] = 1
    else:
         df[idx][col] = 2

我认为必须有一些熊猫的方法或者我缺少的东西。

1 个答案:

答案 0 :(得分:2)

如果我已经理解了这个问题,那么你有一个包含一些空数据的DataFrame,你想用一些已知方式分配的值替换它们。

使用DataFrame.stackDataFrame.unstack方法以及pd.cut的以下方法可以满足您的需求。

首先,生成一些代表您的问题的虚拟数据(这里我们有一个10x3 DataFrame填充随机数据,随机位置插入np.nan值):

_nr, _nc = 10, 3
_rnd = np.random.random((_nr, _nc))
_data = pd.DataFrame(columns=['col{}'.format(x) for x in range(_nc)], data=_rnd)
_stacked = _data.stack()
_nullidx = np.random.randint(0, _stacked.size-1, int(.80*_stacked.size))
_stacked.iloc[_nullidx] = np.nan
data = _stacked.unstack()

这会生成以下内容:

print(data)

       col0      col1      col2
0  0.415485       NaN       NaN
1       NaN       NaN  0.799004
2       NaN  0.359693       NaN
3       NaN       NaN  0.536442
4  0.733635       NaN       NaN
5       NaN       NaN       NaN
6  0.574215       NaN       NaN
7       NaN  0.949404       NaN
8       NaN  0.384289  0.633768
9  0.607698  0.266648  0.639140

我们想要做的是将这些np.nan值填充为0,1或2,具体取决于[0,1]上关于以下频率的均匀分布的绘制:

freqs = 0.03839203180624546, 0.37367433995536975, 0.5879336282383848

为实现这一目标,我们进行堆叠,切割,然后拆开:

stacked = data.copy().stack(dropna=False)
stacked[stacked.isnull()] = \
            pd.cut(np.random.random(stacked.isnull().sum()), 
                   np.cumsum(np.insert(freqs,0,0.)), labels=(0,1,2))
result = stacked.unstack()

这给出了:

print(result)

       col0      col1      col2
0  0.415485  2.000000  2.000000
1  2.000000  2.000000  0.799004
2  1.000000  0.359693  2.000000
3  1.000000  2.000000  0.536442
4  0.733635  0.000000  1.000000
5  2.000000  2.000000  2.000000
6  0.574215  2.000000  2.000000
7  1.000000  0.949404  2.000000
8  2.000000  0.384289  0.633768
9  0.607698  0.266648  0.639140