如何更快的在python中遍历numpy数组

2024-10-03 19:29:36 发布

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

我想知道是否有更好的方法来迭代numpy数组? 我已经对我的嵌套迭代进行了计时,每次循环大约需要40-50秒,我想知道有没有更快的方法来完成它?我知道在numpy数组中循环并不理想,但是我已经束手无策了!我看了很多关于stackoverflow的问题,但是所有的问题都让我更加困惑。在

我尝试过使用tolist()函数将numpy数组转换为一个列表,但是运行时同样慢,如果不是更糟的话。在

def euc_distance(array1, array2):
    return np.power(np.sum((array1 - array2)**2) , 0.5)

for i in range(N):
    for j,n in enumerate(data2.values): 
        distance = euc_distance(n, D[i]) 
        if distance < Dradius[i] and NormAttListTest[j] == "Attack":
            TP += 1

我的euc_距离函数以数组形式(在我的例子中是5维)传递输入,以输出一维值。我的data2.values是通过pandas框架访问numpy数组的方法,pandas框架是一个[500000,5]数据帧。 (请注意,NormAttListTest是一个列表,它将“攻击”和“正常”分类数据标记到每个单独的测试数据上)


Tags: 方法函数innumpy列表fornp数组
1条回答
网友
1楼 · 发布于 2024-10-03 19:29:36

你的问题是你用错了numpy,因为numpy都是关于像MATLAB这样的矢量化计算。考虑对代码的以下修改。我用简单的numpy代码替换了numpy数组上的循环,它有效地利用了2d数组的矢量化。结果代码运行速度快了100倍。在

import functools
import numpy as np
import time

# decorator to measure running time
def measure_running_time(echo=True):
    def decorator(func):
        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            t_1 = time.time()
            ans = func(*args, **kwargs)
            t_2 = time.time()
            if echo:
                print(f'{func.__name__}() running time is {t_2 - t_1:.2f} s')
            return ans
        return wrapped
    return decorator


def euc_distance(array1, array2):
    return np.power(np.sum((array1 - array2) ** 2), 0.5)

# original function
@measure_running_time()
def calculate_TP_1(N, data2, D, Dradius, NormAttListTest, TP=0):
    for i in range(N):
        for j, n in enumerate(data2):
            distance = euc_distance(n, D[i])
            if distance < Dradius[i] and NormAttListTest[j] == "Attack":
                TP += 1
    return TP

# new version
@measure_running_time()
def calculate_TP_2(N, data2, D, Dradius, NormAttListTest, TP=0):

    # this condition is the same for every i value
    NormAttListTest = np.array([val == 'Attack' for val in NormAttListTest])

    for i in range(N):

        # don't use loop over numpy arrays

        # compute distance for all the rows
        distance = np.sum((data2 - D[i]) ** 2, axis=1) ** .5
        # check conditions for all the row
        TP += np.sum((distance < Dradius[i]) & (NormAttListTest))

    return TP


if __name__ == '__main__':

    N = 10
    NN = 100_000
    D = np.random.randint(0, 10, (N, 5))
    Dradius = np.random.randint(0, 10, (N,))
    NormAttListTest = ['Attack'] * NN
    NormAttListTest[:NN // 2] = ['Defence'] * (NN // 2)
    data2 = np.random.randint(0, 10, (NN, 5))

    print(calculate_TP_1(N, data2, D, Dradius, NormAttListTest))

    print(calculate_TP_2(N, data2, D, Dradius, NormAttListTest))

输出:

^{pr2}$

相关问题 更多 >