考虑到分布,我需要替换列中的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
我认为必须有一些熊猫的方法或者我缺少的东西。
答案 0 :(得分:2)
如果我已经理解了这个问题,那么你有一个包含一些空数据的DataFrame,你想用一些已知方式分配的值替换它们。
使用DataFrame.stack
和DataFrame.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