计算python数组中不同元素的平均值的最快方法是什么?

2024-05-17 06:22:52 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的Python代码大约在2 sec中执行。C中的等效代码在6 ms中执行。你知道吗

一些解释:我有2个ADC通道的串行数据(adc0adc1adc0adc1,…)。 如果adc1 <= 10我必须在和中加adc1,否则我必须加adc0。这些值乘以不同的系数(0.10.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最快的方法是什么?你知道吗


Tags: 代码importnumpylentimenpstartdd
2条回答

首先,您需要修正平均计算值(运算符优先级):

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)

有很多方法可以加速。这里有一个使用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}

Obs:我假设这两个函数之间的sumavg的差异源于如何处理浮点精度,但我不确定。 对于您的用例,您需要考虑几个小数位?这个小小的差别重要吗?你知道吗

相关问题 更多 >