Инициализация массива NumPy (заполнить одинаковыми значениями) - PullRequest
192 голосов
/ 05 мая 2011

Мне нужно создать массив NumPy длиной n, каждый элемент которого равен v.

Есть ли что-нибудь лучше, чем:

a = empty(n)
for i in range(n):
    a[i] = v

Я знаю, zeros и ones будут работать для v = 0, 1. Я мог бы использовать v * ones(n), но он не будет работать, когда v равен None, а также будет намного медленнее.

Ответы [ 7 ]

248 голосов
/ 16 декабря 2013

Введено 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]])

Это, вероятно, способ создания массива, заполненного определенными значениями, потому что он явно описывает то, что достигается (и в принципе он может быть очень эффективным, поскольку он выполняет очень специфическую задачу).

85 голосов
/ 24 октября 2012

Обновлено для Numpy 1.7.0: (Наконечник шляпы @Rolf Bartstra.)

a=np.empty(n); a.fill(5) самый быстрый.

В порядке убывания скорости:

%timeit a=np.empty(1e4); a.fill(5)
100000 loops, best of 3: 5.85 us per loop

%timeit a=np.empty(1e4); a[:]=5 
100000 loops, best of 3: 7.15 us per loop

%timeit a=np.ones(1e4)*5
10000 loops, best of 3: 22.9 us per loop

%timeit a=np.repeat(5,(1e4))
10000 loops, best of 3: 81.7 us per loop

%timeit a=np.tile(5,[1e4])
10000 loops, best of 3: 82.9 us per loop
60 голосов
/ 05 мая 2011

Я считаю, fill - самый быстрый способ сделать это.

a = np.empty(10)
a.fill(7)

Вы также должны всегда избегать итераций, как вы делаете в своем примере. Простой a[:] = v выполнит то, что делает ваша итерация, используя numpy broadcasting .

13 голосов
/ 05 ноября 2012

Очевидно, что не только абсолютные скорости, но и скорость порядка (как сообщается пользователем 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!)

Итак, попробуйте и выясните, и используйте самое быстрое на вашей платформе.

9 голосов
/ 05 июля 2017

у меня было

numpy.array(n * [value])

в виду, но, видимо, это медленнее, чем все другие предложения для достаточно большого n.

Вот полное сравнение с perfplot (мой любимый проект).

enter image description here

Две 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,
    )
6 голосов
/ 23 октября 2012

Вы можете использовать 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 предназначен для «разбиения» массива (вместо скаляра, как в данном случае), он будет выполнять эту работу, создавая предварительно заполненные массивы любого размера и размера.

1 голос
/ 09 июля 2018

без NumPy

>>>[2]*3
[2, 2, 2]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...