NumPy 数组初始化(用相同的值填充)[重复]
- 2025-03-18 08:56:00
- admin 原创
- 63
问题描述:
我需要创建一个长度为 的 NumPy 数组n
,其中每个元素都是v
。
还有什么比以下更好的吗:
a = empty(n)
for i in range(n):
a[i] = v
我知道zeros
并且ones
适用于v = 0, 1。我可以使用v * ones(n)
,但当为时它将不起作用,并且也会慢得多。v
`None`
解决方案 1:
NumPy 1.8 引入了,这是一种比创建填充特定值的数组np.full()
更直接的方法:empty()
`fill()`
>>> np.full((3, 5), 7)
array([[ 7., 7., 7., 7., 7.],
[ 7., 7., 7., 7., 7.],
[ 7., 7., 7., 7., 7.]])
>>> np.full((3, 5), 7, dtype=int)
array([[7, 7, 7, 7, 7],
[7, 7, 7, 7, 7],
[7, 7, 7, 7, 7]])
这可以说是创建填充特定值的数组的方式,因为它明确描述了正在实现的目标(并且由于它执行非常具体的任务,因此原则上它可以非常高效)。
解决方案 2:
针对 Numpy 1.7.0 进行了更新:(感谢@Rolf Bartstra。)
a=np.empty(n); a.fill(5)
是最快的。
按速度降序排列:
%timeit a=np.empty(10000); a.fill(5)
100000 loops, best of 3: 5.85 us per loop
%timeit a=np.empty(10000); a[:]=5
100000 loops, best of 3: 7.15 us per loop
%timeit a=np.ones(10000)*5
10000 loops, best of 3: 22.9 us per loop
%timeit a=np.repeat(5,(10000))
10000 loops, best of 3: 81.7 us per loop
%timeit a=np.tile(5,[10000])
10000 loops, best of 3: 82.9 us per loop
解决方案 3:
我相信fill
这是最快的方法。
a = np.empty(10)
a.fill(7)
您还应始终避免像示例中那样进行迭代。一个简单的方法将使用 numpy广播a[:] = v
完成迭代所做的事情。
解决方案 4:
我曾 np.array(n * [value])
考虑过,但显然这比其他所有足够大的建议都慢n
。在可读性和速度方面最好的是
np.full(n, 3.14)
这是与perfplot(我的一个小项目)的完整比较。
这两个empty
替代方案仍然是最快的(使用 NumPy 1.12.1)。full
赶上大型数组。
生成图表的代码:
import numpy as np
import perfplot
def empty_fill(n):
a = np.empty(n)
a.fill(3.14)
return a
def empty_colon(n):
a = np.empty(n)
a[:] = 3.14
return a
def ones_times(n):
return 3.14 * np.ones(n)
def repeat(n):
return np.repeat(3.14, (n))
def tile(n):
return np.repeat(3.14, [n])
def full(n):
return np.full((n), 3.14)
def list_to_array(n):
return np.array(n * [3.14])
perfplot.show(
setup=lambda n: n,
kernels=[empty_fill, empty_colon, ones_times, repeat, tile, full, list_to_array],
n_range=[2 ** k for k in range(27)],
xlabel="len(a)",
logx=True,
logy=True,
)
解决方案 5:
显然,不仅绝对速度而且速度顺序(由用户 1579844 报告)都与机器有关;这是我发现的:
a=np.empty(1e4); a.fill(5)
是最快的;
按速度降序排列:
timeit a=np.empty(1e4); a.fill(5)
# 100000 loops, best of 3: 10.2 us per loop
timeit a=np.empty(1e4); a[:]=5
# 100000 loops, best of 3: 16.9 us per loop
timeit a=np.ones(1e4)*5
# 100000 loops, best of 3: 32.2 us per loop
timeit a=np.tile(5,[1e4])
# 10000 loops, best of 3: 90.9 us per loop
timeit a=np.repeat(5,(1e4))
# 10000 loops, best of 3: 98.3 us per loop
timeit a=np.array([5]*int(1e4))
# 1000 loops, best of 3: 1.69 ms per loop (slowest BY FAR!)
因此,请尝试找出并使用在您的平台上最快的方法。
解决方案 6:
没有 numpy
>>>[2]*3
[2, 2, 2]
解决方案 7:
您可以使用numpy.tile
,例如:
v = 7
rows = 3
cols = 5
a = numpy.tile(v, (rows,cols))
a
Out[1]:
array([[7, 7, 7, 7, 7],
[7, 7, 7, 7, 7],
[7, 7, 7, 7, 7]])
尽管tile
其目的是“平铺”一个数组(而不是像本例中那样平铺一个标量),但它可以完成这项工作,创建任意大小和维度的预填充数组。
解决方案 8:
我们也可以写
v=7
n=5
a=np.linspace(v,v,n)
解决方案 9:
您也可以使用np.broadcast_to
。
s
要创建形状(尺寸)和值的数组v
,您可以执行以下操作(在您的情况下,数组是一维的,并且s = (n,)
):
a = np.broadcast_to(v, s).copy()
如果a
只需要只读,则可以使用以下方法(效率更高):
a = np.broadcast_to(v, s)
优点是v
可以将 给出为单个数字,但如果需要不同的值,也可以将其给出为数组(只要v.shape
匹配 的尾部s
)。
奖励:如果您想强制dtype
创建数组:
a = np.broadcast_to(np.asarray(v, dtype), s).copy()
扫码咨询,免费领取项目管理大礼包!