Python Numpy добавление нескольких списков из объектов - PullRequest
0 голосов
/ 29 августа 2018

Я несколько раз вызываю объект, который возвращает список с пустым адресом:

for x in range(0,100):
        d = simulation3()

d = [0, 1, 2, 3]
d = [4, 5, 6, 7]

.. и многие другие

Я хочу взять каждый список и добавить его в двумерный массив.

final_array = [[0, 1, 2, 3],[4, 5, 6, 7] ... и т. Д.]

Я попытался создать пустой массив (final_array = np.zeros(4,4)) и добавить его, но значения добавляются после создания 4X4 matrix.

Может кто-нибудь помочь мне с этим? спасибо!

Ответы [ 3 ]

0 голосов
/ 29 августа 2018

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

Если вы не знаете размер конечного результата, то вам лучше создать список списков, который можно преобразовать (или собрать в стек) в виде массива NumPy в конце процесса.

Вот несколько примеров, где gen_1d_list() используется для генерации случайных чисел, имитирующих результат simulate3() (это означает, что в следующем коде вы должны заменить gen_1d_list(n, dtype) на simulate3()):

  • stacking1() реализует заполнение с использованием представлений
  • stacking2() реализует генерацию списка и преобразовывает в массив NumPy
  • stacking3() реализует генерацию списка и укладку в массив NumPy
  • stacking4() реализует динамическое изменение массива NumPy с использованием vstack(), как предлагалось ранее.
import numpy as np

def gen_1d_list(n, dtype=int):
    return list(np.random.randint(1, 100, n, dtype))

def stacking1(n, m, dtype=int):
    arr = np.empty((n, m), dtype=dtype)
    for i in range(n):
        arr[i] = gen_1d_list(m, dtype)
    return arr

def stacking2(n, m, dtype=int):
    items = [gen_1d_list(m, dtype) for i in range(n)]
    arr = np.array(items)
    return arr

def stacking3(n, m, dtype=int):
    items = [gen_1d_list(m, dtype) for i in range(n)]
    arr = np.stack(items, dtype)
    return arr

def stacking4(n, m, dtype=int):
    arr = np.zeros((0, m), dtype=dtype)
    for i in range(n):
        arr = np.vstack((gen_1d_list(m, dtype), arr))
    return arr

По времени stacking1() и stacking2() более или менее одинаково быстро, в то время как stacking3() и stacking4() медленнее (и, пропорционально, намного медленнее для входов малого размера).

Некоторые цифры для небольших входных данных:

n, m = 4, 10
%timeit stacking1(n, m)
# 15.7 µs ± 182 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit stacking2(n, m)
# 14.2 µs ± 141 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit stacking3(n, m)
# 22.7 µs ± 282 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit stacking4(n, m)
# 31.8 µs ± 270 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

и для входов большего размера:

n, m = 4, 1000000
%timeit stacking1(n, m)
# 344 ms ± 1.64 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit stacking2(n, m)
# 350 ms ± 1.65 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit stacking3(n, m)
# 370 ms ± 2.75 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit stacking4(n, m)
# 369 ms ± 3.01 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
0 голосов
/ 29 августа 2018

Вы можете использовать np.fromiter для создания массива из итерируемого. Поскольку по умолчанию эта функция работает только со скалярами, вы можете использовать itertools.chain, чтобы помочь:

np.random.seed(0)

from itertools import chain

def simulation3():
    return np.random.randint(0, 10, 4)

n = 5
d = np.fromiter(chain.from_iterable(simulation3() for _ in range(5)), dtype='i')
d.shape = 5, 4

print(d)

array([[5, 0, 3, 3],
       [7, 9, 3, 5],
       [2, 4, 7, 6],
       [8, 8, 1, 6],
       [7, 7, 8, 1]], dtype=int32)

Но это относительно неэффективно. NumPy лучше всего работает с массивами фиксированного размера. Если вы заранее знаете размер вашего массива, вы можете определить пустой массив и последовательно обновлять строки. См. альтернативы , описанные @ norok2.

0 голосов
/ 29 августа 2018

Есть несколько способов сделать это в numpy, самый простой способ - использовать vstack следующим образом:

Например:

#you have these array you want to concat

d1 = [0, 1, 2, 3]
d2 = [4, 5, 6, 7]
d3 = [4, 5, 6, 7]

#initialize your variable with zero raw 
X = np.zeros((0,4))

#then each time you call your function use np.vstack like this :
X = np.vstack((np.array(d1),X))
X = np.vstack((np.array(d2),X))
X = np.vstack((np.array(d2),X))

# and finally you have your array like below
#array([[4., 5., 6., 7.],
#       [4., 5., 6., 7.],
#       [0., 1., 2., 3.]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...