Есть ли у них способ разделить один 2d-массив на несколько одномерных массивов различной формы, используя 1-й столбец в качестве индекса?

#python #arrays #numpy #sorting

#python #массивы #numpy #сортировка

Вопрос:

Я пытаюсь разделить 2d-массив numpy на несколько одномерных массивов 2-го столбца, используя первый столбец в качестве индекса. 2d-массив очень большой (2100000)

в принципе, у меня есть массив, который выглядит так (только намного больше):

 [[1,a]
 [1,a2]
 [1,a3]
  ....
 [100,b]
 [100,b2]]
 

Я хочу разделить его на два массива, которые выглядят так

 [a,a2,a3]
 

и

 [b,b2]
 

Я даже не уверен, с чего начать или выполнить поиск, и был бы очень признателен за любую помощь

Ответ №1:

Вы ищете itertools.groupby . Вам нужно указать key функцию, которая определяет, как группировать элементы в вашем вложенном list (в данном случае по первому элементу). В этом случае мы можем использовать itemgetter .

Согласно вашим требованиям, вы хотите, чтобы каждая группа содержала только второй элемент исходных данных, так itemgetter что это тоже может помочь.

 from itertools import groupby
from operator import itemgetter

data = [[1, 'a'],
        [1, 'b'],
        [1, 'c'],
        [2, 'a'],
        [2, 'b'],
        [3, 'c']]

result = {key: list(map(itemgetter(1), group)) for key, group in groupby(data, key=itemgetter(0))}

print(result)
 

Вывод:

 {1: ['a', 'b', 'c'], 2: ['a', 'b'], 3: ['c']}
 

Обратите внимание, что сначала вы должны отсортировать вложенные входные list данные, если ключи еще не в порядке, в противном случае они будут разделены на несколько групп с одним и тем же ключом.

Ответ №2:

Вы можете использовать np.flatnonzero (или np.nonzero или np.where ) и np.diff , чтобы найти границы блоков, а затем разделить с помощью np.split :

 # create example
x = np.c_[np.repeat(*sum(np.ogrid[:2, 1:4])), 1:10]
x
# array([[1, 1],
#        [1, 2],
#        [2, 3],
#        [2, 4],
#        [2, 5],
#        [3, 6],
#        [3, 7],
#        [3, 8],
#        [3, 9]])
np.split(x[:, 1], np.flatnonzero(np.diff(x[:, 0]))   1)
# [array([1, 2]), array([3, 4, 5]), array([6, 7, 8, 9])]