向numpy数组添加值的最快方法

lnvxswe2  于 2023-03-30  发布在  其他
关注(0)|答案(4)|浏览(173)

我需要在循环中向一个numpy数组中添加很多值(大约100k),并且知道以下方法:

import numpy as np
import time

#Method 1:
start = time.time()
b = np.array([0.0])
for i in range (1, 100000):
    b = np.append(b, np.array([i]))
end = time.time()
print(end-start)

#Method 2:
start = time.time()
a = np.array([0])
A = np.empty(99999) * np.nan
a = np.concatenate((a, A), axis=0)
for i in range (1, 100000):
    a[i] = i
end = time.time()
print(end-start)

_______________________________
result:
3.2555339336395264
0.018993854522705078

正如你所看到的,方法2更快,但问题是我必须从数组中删除np.nan(因为我不知道应该向数组中添加多少值,所以我创建了比它应该更大的np.nan数组)。

vwoqyblh

vwoqyblh2#

如果你要添加的是一个常量值,你可以使用np array +一个常量值来添加数组的每个元素。因为它不是100%你初始化的目的,你也可以使用arange来设置数组。

import time

start = time.time()
a = np.arange(100000)
a = a+3
end = time.time()
print(end-start)

___________________________
result: 0.0007009506225585938
roqulrg3

roqulrg33#

据我所知,第二种方法是最佳的,当大小不能事先确定,你不能预测任何关于值。在这种情况下,np.isnan()函数可以用来消除空值。
此外,将空数组乘以np.nan是不必要的。这里有一个替代实现(方法3),我希望它能有所帮助:

import numpy as np
import time

#Method 1:
start = time.time()
b = np.array([0.0])
for i in range (1, 100000):
    b = np.append(b, np.array([i]))
end = time.time()
print(end-start)

#Method 2:
start = time.time()
a = np.array([0])
A = np.empty(99999) * np.nan
a = np.concatenate((a, A), axis=0)
for i in range (1, 100000):
    a[i] = i
end = time.time()
print(end-start)

#Method 3:
start = time.time()
a = np.array([0])
A = np.empty(99999)
a = np.concatenate((a, A), axis=0)
for i in range (1, 100000):
    a[i] = i
a_new = a[~np.isnan(a)]
end = time.time()
print(end-start)

输出:

4.930854797363281
0.020646095275878906
0.018013954162597656

Process finished with exit code 0
xghobddn

xghobddn4#

这完全取决于你的最终情况是什么。如果你提前知道你会有多少输入-就像你的玩具例子一样-那么你就可以分配一个足够大的数组。至于“从我的数组中删除np.nan”:只要知道它包含多少有效项,就可以创建过度分配数组的切片视图。
在数据不断进入的一般流式传输情况下,最佳策略是根据需要调整大小,将数组大小增加一个因子,例如2:

# Method 3
start = time.time()
a = np.array([0])
A = np.empty(100)  # Inappropriately small initial size
a = np.concatenate((a, A), axis=0)

LEN = 100000
for i in range (1, LEN):
   if i >= len(a):
       a.resize(len(a) * 2)
   a[i] = i
a = a[:LEN]  # truncated view

end = time.time()
print(end-start)

如果你有一个长度未知的输入,这是更合适的。在这种情况下,array.array is a much better option用于缓冲输入,然后你可以转换为ndarray用于计算。

# Method 4
import array
start = time.time()
a = array.array("d")  # Assuming float data
a.append(0)

LEN = 100000
for i in range (1, LEN):
   a.append(i)

a = np.frombuffer(a, dtype=float)

end = time.time()
print(end-start)

相关问题