更快的方法来替换每列的特定值,python

时间:2016-07-13 04:15:01

标签: python pandas

我有一个大型结构作为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

有更快的解决方案吗?

2 个答案:

答案 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.whereaavg之间进行选择。将其包装在pd.DataFrame构造函数中。

pd.DataFrame(np.where(a != 2, a, avg), df.index, df.columns)