如何在Python中创建指定维度、特定类型且初始值相同的数组?

6 投票
4 回答
17974 浏览
提问于 2025-04-16 22:58

我想在Python中创建一个指定维度和特定类型的数组,并且这个数组里的每个值都要初始化为相同的值。我可以使用numpy来创建特定大小的数组,但我不太确定怎么把它们初始化为一个特定的值。当然,我不想用零或者一来初始化。

非常感谢。

4 个回答

3

从NumPy 1.8版本开始,你可以使用 numpy.full() 来实现这个功能。

>>> import numpy as np
>>> np.full((3,4), 100, dtype = int)
array([[ 100,  100,  100,  100],
       [ 100,  100,  100,  100],
       [ 100,  100,  100,  100]])
6

这样做怎么样:

shape = (100,100)
val = 3.14
dt = np.float
a = np.empty(shape,dtype=dt)
a.fill(val)

这样你可以设置一些东西并传入参数。而且在时间方面,

In [35]: %timeit a=np.empty(shape,dtype=dt); a.fill(val)
100000 loops, best of 3: 13 us per loop

In [36]: %timeit a=np.tile(val,shape)
10000 loops, best of 3: 102 us per loop

所以使用 emptyfill 的速度明显比 tile 快。

13

有很多方法可以做到这一点。我想到的第一个简单的方法是 tile

>>> numpy.tile(2, 25)
array([2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
       2, 2, 2, 2, 2])

你可以用它把一个值铺成任何形状:

>>> numpy.tile(2, (5, 5))
array([[2, 2, 2, 2, 2],
       [2, 2, 2, 2, 2],
       [2, 2, 2, 2, 2],
       [2, 2, 2, 2, 2],
       [2, 2, 2, 2, 2]])

不过,下面的一些回答指出,这并不是最快的方法。它是为了处理任何大小的数组而设计的,而不仅仅是单个值。所以如果你只是想用一个值填充一个数组,先分配数组,然后使用切片赋值的方法会快得多:

>>> a = numpy.empty((5, 5), dtype=int)
>>> a[:] = 2
>>> a
array([[2, 2, 2, 2, 2],
       [2, 2, 2, 2, 2],
       [2, 2, 2, 2, 2],
       [2, 2, 2, 2, 2],
       [2, 2, 2, 2, 2]])

根据我做的一些测试,没有比这更快的方法了。不过,下面提到的两种方法速度是一样快的:ndarray.fillnumpy.full

这些测试都是在 ipython 中进行的,使用的是 Python 3.6.1,在一台运行 OS 10.12.6 的新款 Mac 上。

def fill_tile(value, shape):
    return numpy.tile(value, shape)

def fill_assign(value, shape, dtype):
    new = numpy.empty(shape, dtype=dtype)
    new[:] = value
    return new

def fill_fill(value, shape, dtype):
    new = numpy.empty(shape, dtype=dtype)
    new.fill(value)
    return new

def fill_full(value, shape, dtype):
    return numpy.full(shape, value, dtype=dtype)

def fill_plus(value, shape, dtype):
    new = numpy.zeros(shape, dtype=dtype)
    new += value
    return new

def fill_plus_oneline(value, shape, dtype):
    return numpy.zeros(shape, dtype=dtype) + value

for f in [fill_assign, fill_fill, fill_full, fill_plus, fill_plus_oneline]:
    assert (fill_tile(2, (500, 500)) == f(2, (500, 500), int)).all()

tile 的确比较慢:

In [3]: %timeit fill_tile(2, (500, 500))
947 µs ± 10.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

切片赋值与 ndarray.fillnumpy.full 并列第一:

In [4]: %timeit fill_assign(2, (500, 500), int)
102 µs ± 1.37 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [5]: %timeit fill_fill(2, (500, 500), int)
102 µs ± 1.99 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [6]: %timeit fill_full(2, (500, 500), int)
102 µs ± 1.47 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

就地广播加法只慢了一点:

In [7]: %timeit fill_plus(2, (500, 500), int)
179 µs ± 3.7 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

而非就地广播加法只比这个稍微慢一点:

In [8]: %timeit fill_plus_oneline(2, (500, 500), int)
213 µs ± 4.74 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

撰写回答