Как я могу сделать генератор, который перебирает двумерный массив? - PullRequest
1 голос
/ 11 марта 2019

У меня есть огромный двумерный массив, который я хочу получить партиями. Форма массива = 60000,3072 Я хочу создать генератор, который даст мне фрагменты из этого массива, например: 1000,3072, затем следующий 1000,3072 и так далее. Как я могу сделать генератор для итерации по этому массиву и передать мне пакет заданного размера?

Ответы [ 3 ]

2 голосов
/ 11 марта 2019

рассмотрим массив a

a = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9],
              [10, 11, 12]])

Вариант 1
Используйте генератор

def get_every_n(a, n=2):
    for i in range(a.shape[0] // n):
        yield a[n*i:n*(i+1)]

for sa in get_every_n(a):
    print sa

[[1 2 3]
 [4 5 6]]
[[ 7  8  9]
 [10 11 12]]

Вариант 2
используйте reshape и //

a.reshape(a.shape[0] // 2, -1, a.shape[1])

array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])

Вариант 3
если вы хотели группы из двух, а не двух групп

a.reshape(-1, 2, a.shape[1])

array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])

Поскольку вы прямо указали, что вам нужен генератор, вы можете использовать опцию 1 в качестве соответствующей ссылки.

1 голос
/ 11 марта 2019

Вот данные, которые у вас есть:

import numpy as np
full_len = 5    # In your case, 60_000
cols = 3        # In your case, 3072

nd1 = np.arange(full_len*cols).reshape(full_len,cols)

Вот что вы можете сделать, чтобы «сгенерировать» фрагменты:

Вариант 1, Использование numpy.array_split ():

from math import ceil

step_size = 2   # In your case, 1_000
split_list = np.array_split(nd1,ceil(full_len/step_size), axis=0)
print (split_list)

split_list теперь является списком срезов в nd1.Зацикливая этот список, вы можете получить доступ к отдельным слайсам как split_list[0], split_list[1] и т. Д., И каждый из этих слайсов будет представлять собой nd1 и может использоваться точно так же, как и любой другой массив с нулевыми значениями..

Вывод для варианта 1:

Вот вывод, показывающий, что последний фрагмент был немного короче, чем другие обычные:

[array([[0, 1, 2],
       [3, 4, 5]]), array([[ 6,  7,  8],
       [ 9, 10, 11]]), array([[12, 13, 14]])]

Параметр2, с помощью явного среза:

step_size = 2   # In your case, 1_000
myrange = range(0, full_len, step_size)

for r in myrange:
    my_slice_array = nd1 [r:r+step_size]
    print (my_slice_array.shape)

Вывод для варианта 2:

(2, 3)
(2, 3)
(1, 3)

Обратите внимание, что в отличие от нарезки списков, нарезка массива с пустым фрагментом не делает копию источникаданные массива.Это только создает представление в пределах границ среза, на основе существующих данных исходного массива.Это относится как к Вариант 1 , так и к Вариант 2 , так как оба включают создание срезов.

0 голосов
/ 11 марта 2019

Если вы хотите что-то с помощью генератора, это решение ниже работает

import numpy 
bigArray = numpy.random.rand(60000, 3072) # have used this to generate dummy array

def selectArray(m,n):
  yield bigArray[m, n] # I am facing issue with giving proper slices. Please handle it yourselg. 

genObject = selectArray(1000, 3072)

, и вы можете использовать либо for цикл, либо next(), чтобы перебрать genObject.

Примечание: если вы используете next(), убедитесь, что вы обрабатываете StopIteration исключение.

Надеюсь, это поможет.

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