我有一个大型结构作为pandas数据帧,shape =(2000,200000)我想用每个列中的特定列替换所有2的值(不包括2个值)。这就是我如何为小型结构做的,但对于较大的结构,它需要相当长的时间。 Y
是DataFrame。
for i in Y.columns:
x = Y[i][Y[i] != 2].mean()
Y[i][Y[i] == 2] = x
有更快的解决方案吗?
答案 0 :(得分:3)
由于您正在使用算术运算,我建议将所有这些计算卸载到NumPy,获取最终结果并创建数据帧,如此 -
# Extract into an array
arr = Y.values
# Mask to set or not-set elements in array
mask = arr!=2
# Compute the mean vaalues for masked elements along each column
avg = np.true_divide((arr*mask).sum(0),mask.sum(0))
# Finally choose values based on mask and create output dataframe
Yout = pd.DataFrame(np.where(~mask,avg,arr),columns=Y.columns)
为了进一步提升性能,您可以将(arr*mask).sum(0)
替换为np.einsum('ij,ij->j',arr,mask)
,因为np.einsum
在大多数情况下非常有效。
使用样本运行验证结果 -
In [128]: Y = pd.DataFrame(np.random.randint(0,4,(10,5)))
In [129]: arr = Y.values
...: mask = arr!=2
...: avg = np.true_divide((arr*mask).sum(0),mask.sum(0))
...: Yout = pd.DataFrame(np.where(~mask,avg,arr),columns=Y.columns)
...:
In [130]: for i in Y.columns:
...: x = Y[i][Y[i] != 2].mean()
...: Y[i][Y[i] == 2] = x
...:
In [131]: np.allclose(Y,Yout)
Out[131]: True
答案 1 :(得分:1)
假设您的数据框为df
,请:
a = df.values
我会用
来计算非二人的平均值avg = (a.sum(0) - (a == 2).sum(0) * 2.) / (a != 2).sum(0)
(a == 2).sum(0)
是每列中2
的数量。
然后使用np.where
在a
和avg
之间进行选择。将其包装在pd.DataFrame
构造函数中。
pd.DataFrame(np.where(a != 2, a, avg), df.index, df.columns)