优化给定操作,是否有更好的方法?

问题描述

我是新手,我需要一些见识。假设我有一个熊猫数据框,如下所示:

temp = pd.DataFrame()
temp['A'] = np.random.rand(100)
temp['B'] = np.random.rand(100)
temp['C'] = np.random.rand(100)

我需要编写一个函数,如果“ A”的值在相应行中大于0.5,则将“ C”列中的每个值替换为0。否则,我需要在同一行中将A和B逐个元素相乘,并在“ C”列的相应行上写下输出

我到目前为止所做的是:

A=temp.loc[temp['A']<0.5,'A'].values
B=temp.loc[temp['A']<0.5,'B'].values
temp['C'] = 0
temp.loc[temp['A']<0.5,'C']=A*B

它可以按我希望的方式工作,但是我不确定是否有更快的方法来实现。我非常怀疑,尤其是在切片时,我觉得使用这么多切片很丰富。但是,我找不到其他解决方案,因为我必须为A大于0.5的C行写0。

或者,是否可以将仅需要的部分切成薄片,进行计算,然后以某种方式记住索引,以便可以将所需的值放回相应行的原始数据框中? strong>

解决方法

使用numpy.where的一种方式:

temp["C"] = np.where(temp["A"]<0.5,temp["A"] * temp["B"],0)

基准测试(采样速度提高约4倍,并且还在不断提高):

# With given sample of 100 rows

%%timeit
A=temp.loc[temp['A']<0.5,'A'].values
B=temp.loc[temp['A']<0.5,'B'].values
temp['C'] = 0
temp.loc[temp['A']<0.5,'C']=A*B

# 819 µs ± 2.77 µs per loop (mean ± std. dev. of 7 runs,1000 loops each)

%timeit np.where(temp["A"]<0.5,0)

# 174 µs ± 455 ns per loop (mean ± std. dev. of 7 runs,10000 loops each)

对更大数据进行基准测试(速度提高约7倍)

temp = pd.DataFrame()
temp['A'] = np.random.rand(1000000)
temp['B'] = np.random.rand(1000000)
temp['C'] = np.random.rand(1000000)

%%timeit
A=temp.loc[temp['A']<0.5,'C']=A*B

# 35.2 ms ± 345 µs per loop (mean ± std. dev. of 7 runs,10 loops each)

%timeit np.where(temp["A"]<0.5,0)

# 5.16 ms ± 188 µs per loop (mean ± std. dev. of 7 runs,100 loops each)

验证

A=temp.loc[temp['A']<0.5,'C']=A*B
np.array_equal(temp["C"],np.where(temp["A"]<0.5,0))
# True