Skip to main content
 首页 » 编程设计

python之从元组列表中为每个项目创建 np.arrays 的最快方法

2025年05月04日21soundcode

有一个元组列表l = [(x,y,z), (x,y,z), (x,y,z)] 这个想法是找到为每个 x-s、y-s、z-s 创建不同 np.arrays 的最快方法。需要帮助找到最快的解决方案。为了进行速度比较,我使用下面附带的代码

import time 
 
def myfast(): 
   code 
 
n = 1000000 
t0 = time.time() 
for i in range(n): myfast() 
t1 = time.time() 
 
total_n = t1-t0 
 
1.  np.array([i[0] for i in l]) 
    np.array([i[1] for i in l]) 
    np.array([i[2] for i in l]) 

output: 0.9980638027191162

2.  array_x = np.zeros((len(l), 1), dtype="float") 
    array_y  = np.zeros((len(l), 1), dtype="float") 
    array_z  = np.zeros((len(l), 1), dtype="float") 
 
    for i, zxc in enumerate(l): 
        array_x[i] = zxc[0] 
        array_y[i] = zxc[1] 
        array_z[i] = zxc[2] 

output 5.5509934425354

3. [np.array(x) for x in zip(*l)] 

output 2.5070037841796875

5. array_x, array_y, array_z = np.array(list(zip(*l))) 

output 2.725318431854248

请您参考如下方法:

这里有一些非常好的选项,所以我总结了它们并比较了速度:

import numpy as np 
 
def f1(input_data): 
    array_x = np.array([elem[0] for elem in input_data]) 
    array_y = np.array([elem[1] for elem in input_data]) 
    array_z = np.array([elem[2] for elem in input_data]) 
 
    return array_x, array_y, array_z 
 
def f2(input_data): 
    array_x = np.zeros((len(input_data), ), dtype="float") 
    array_y = np.zeros((len(input_data), ), dtype="float") 
    array_z = np.zeros((len(input_data), ), dtype="float") 
 
    for i, elem in enumerate(input_data): 
        array_x[i] = elem[0] 
        array_y[i] = elem[1] 
        array_z[i] = elem[2] 
 
    return array_x, array_y, array_z 
 
def f3(input_data): 
    return [np.array(elem) for elem in zip(*input_data)] 
 
def f4(input_data): 
    return np.array(list(zip(*input_data))) 
 
def f5(input_data): 
    return np.array(input_data).transpose() 
 
def f6(input_data): 
    array_all = np.array(input_data) 
    array_x = array_all[:, 0] 
    array_y = array_all[:, 1] 
    array_z = array_all[:, 2] 
 
    return array_x, array_y, array_z 

首先我断言它们都返回相同的数据(使用 np.array_equal()):

data = [(1, 2, 3), (4, 5, 6), (7, 8, 9)] 
for array_list in zip(f1(data), f2(data), f3(data), f4(data), f5(data), f6(data)): 
    # print() 
    # for i, arr in enumerate(array_list): 
    #     print('array from function', i+1) 
    #     print(arr) 
    for i, arr in enumerate(array_list[:-1]): 
        assert np.array_equal(arr, array_list[i+1]) 

时间比较:

import timeit 
for f in [f1, f2, f3, f4, f5, f6]: 
    t = timeit.timeit('f(data)', 'from __main__ import data, f', number=100000) 
    print('{:5s} {:10.4f} seconds'.format(f.__name__, t)) 

给出这些结果:

data = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]    # 3 tuples 
timeit number=100000 
f1        0.3184 seconds 
f2        0.4013 seconds 
f3        0.2826 seconds 
f4        0.2091 seconds 
f5        0.1732 seconds 
f6        0.2159 seconds 
 
data = [(1, 2, 3) for _ in range(10**6)]    # 1 millon tuples 
timeit number=10 
f1        2.2168 seconds 
f2        2.8657 seconds 
f3        2.0150 seconds 
f4        1.9790 seconds 
f5        2.6380 seconds 
f6        2.6586 seconds 

使 f5() 成为短输入的最快选项,使 f4() 成为大输入的最快选项。


如果每个元组中的元素数量超过 3 个,则只有 3 个函数适用于这种情况(其他函数被硬编码为每个元组中的 3 个元素):

data = [tuple(range(10**4)) for _ in range(10**3)] 
timeit number=10 
f3       11.8396 seconds 
f4       13.4672 seconds 
f5        4.6251 seconds 

再次使 f5() 成为满足这些标准的最快选项。