下面的Python
代码大约执行2 sec
。 C
中的等效代码在6 ms
中执行。
一些解释:我有2个ADC
通道的串行数据(adc0
,adc1
,adc0
,adc1
,...)。
如果adc1 <= 10
必须将adc1
加到总数上,否则必须加上adc0
。这些值乘以不同的系数(0.1
和0.01
)。
#!/usr/bin/env python
import time
import numpy as np
dd = np.random.randint(0, 20, size=(2*1000*1000))
t_start = time.clock()
avg_sum1 = 0.0
BlockOffset = 0
while BlockOffset < len(dd):
if dd[BlockOffset + 1] <= 10:
avg_sum1 += dd[BlockOffset + 1] * 0.1
else:
avg_sum1 += dd[BlockOffset + 0] * 0.01
BlockOffset += 2
print('Avg: ' + str(avg_sum1 / len(dd) / 2))
print('Exe time: ' + str(time.clock() - t_start))
使用内置函数或numpy
最快的方法是什么?
答案 0 :(得分:1)
首先,您需要确定平均计算(运算符优先级):
avg_sum1 / (len(dd) / 2) # or avg_sum1 / len(dd) * 2
Out[]:
0.31740819000001924
2.8 s ± 28.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
您可以在numpy
中执行此操作,例如:
In []:
np.where(dd[1::2] <= 10, dd[1::2]*0.1, dd[0::2]*0.01).mean()
Out[]:
0.31740818999999987
10.8 ms ± 61.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
答案 1 :(得分:-1)
有很多方法可以加快速度。这是使用pandas
的解决方案(也许也可以仅使用numpy
来完成)。
在此代码中,f1()
是您的原始功能,而f2()
使用的是pandas
。
import numpy as np
import pandas as pd
import time
def f1(data):
t_start = time.perf_counter()
offset = 0
sum_1 = 0.0
while offset < data.shape[0]:
if data[offset + 1] <= 10:
sum_1 += data[offset + 1] * 0.1
else:
sum_1 += data[offset + 0] * 0.01
offset += 2
n = data.shape[0] / 2
avg_1 = sum_1 / n
t_end = time.perf_counter()
return {
'calc_time': t_end - t_start,
'n': n,
'sum': sum_1,
'avg': avg_1,
}
def f2(data):
t_start = time.perf_counter()
df = pd.DataFrame()
df['adc0'] = data[0::2] # every second element, starting at 0
df['adc1'] = data[1::2] # every second element, starting at 1
df['sum_value'] = np.where(
df['adc1'] <= 10,
df['adc1'] * 0.1,
df['adc0'] * 0.01)
sum_1 = df['sum_value'].sum()
n = df.shape[0]
avg_1 = sum_1 / n
t_end = time.perf_counter()
return {
'calc_time': t_end - t_start,
'n': n,
'sum': sum_1,
'avg': avg_1,
}
if __name__ == '__main__':
numbers = np.random.randint(0, 20, size=(2*1000*1000))
r = f1(numbers)
print(r)
r = f2(numbers)
print(r)
此代码显示f2()
的速度更快,大约使用123 ms
(不到f1()
时间的10%)。
# f1
{'avg': 0.31791369000003045, 'n': 1000000.0, 'sum': 317913.69000003044,
'calc_time': 4.765112441743648}
# f2
{'avg': 0.31791368999999986, 'n': 1000000, 'sum': 317913.68999999989,
'calc_time': 0.12356162259120662}
肥胖:我假设两个函数之间的sum
和avg
之差源自浮点精度的处理方式,但我不确定。
您需要为用例考虑多少个小数位?这个小的差异重要吗?