给定操作的优化,有没有更好的方法?
Optimization of the given operation, is there a better way?
我是新手,需要一些见识。假设我有一个 pandas 数据框,如下所示:
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。
或者,有没有一种方法可以将只需要的部分切片,进行计算,然后以某种方式记住索引,这样你就可以将所需的值放回相应的原始数据帧中行数?
使用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, temp["A"] * temp["B"], 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, 'A'].values
B=temp.loc[temp['A']<0.5, 'B'].values
temp['C'] = 0
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, temp["A"] * temp["B"], 0)
# 5.16 ms ± 188 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
验证
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
np.array_equal(temp["C"], np.where(temp["A"]<0.5, temp["A"] * temp["B"], 0))
# True
我是新手,需要一些见识。假设我有一个 pandas 数据框,如下所示:
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。
或者,有没有一种方法可以将只需要的部分切片,进行计算,然后以某种方式记住索引,这样你就可以将所需的值放回相应的原始数据帧中行数?
使用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, temp["A"] * temp["B"], 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, 'A'].values
B=temp.loc[temp['A']<0.5, 'B'].values
temp['C'] = 0
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, temp["A"] * temp["B"], 0)
# 5.16 ms ± 188 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
验证
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
np.array_equal(temp["C"], np.where(temp["A"]<0.5, temp["A"] * temp["B"], 0))
# True