Как извлечь определенные числа из массивов numpy на основе повторения чисел

#python #algorithm #numpy

#python #алгоритм #numpy

Вопрос:

У меня есть два массива numpy, и я хочу извлечь из них некоторые конкретные части. Эти массивы:

 arr_A=np.arange(17, 29)
arr_B=np.arange(17, 27)
 

Эти массивы представляют собой количество некоторых точек. Тогда у меня есть другие массивы, которые показывают повторение точек вдоль линий:

 rep_A=np.array([4,4,2,1,1])
rep_B=np.array([1,4,5])
 

Затем для arr_A я хочу извлечь точки, которые находятся в правой части ( 21,22,25,28 ), а для arr_B я хочу точки с левой стороны ( 17,19,20,21,26 ) . Я показал эти точки звездочками на моем рисунке. Я хочу найти способ связать rep s с arr s для поиска уставленных точек. Распределение моих точек может измениться, но я всегда хочу извлекать числа с левой или правой стороны.
Я попробовал следующий код, но он не был успешным вообще:

 points=[]
for i in b:
if i==0:
    points.append(arr_A[-rep_A[-1]:])
    m = len (first[0])
    data=m*2
    if i==-1:
        points.append(arr_A[-data-rep_A[-3]:-data])
 

Я заранее признателен за любую помощь.

введите описание изображения здесь

Ответ №1:

Основываясь на ваших комментариях и разъяснениях, вот способ, которым вы можете решить эту проблему.

Как это работает —

  1. fetch_sublists() генератор разбивает список на sublists и перед pads каждым с 0s.
  2. get_stars() вызывает приведенное выше generator для построения матрицы по stacking массивам, переворачивает нули вверх orientation и сохраняет их в m
  3. Использует эту ориентацию для поиска первых ненулевых элементов из верхнего направления и сохраняет его в star
  4. Поворачивает матрицу в нужном направлении и перезаписывает ее на m
  5. Наконец, возвращает как матрицу, так mat и побочные элементы as star .
 #Generates the sublists with padding 0
def fetch_sublists(arr, rep):
    itr = iter(arr)
    maxlen = np.max(rep)
    for size in rep:
        sublist = []
        for _ in range(size):
            sublist.append(next(itr))
        yield np.pad(sublist, maxlen-size)[:maxlen]
      
#Constructs the matrix based on orientation and returns the side elements
def get_stars(arr, rep, orientation='right'):
    if orientation=='right':
        m = np.flipud(list(fetch_sublists(arr, rep)))
        star_elements = m[(m!=0).argmax(0), np.arange(m.shape[1])]
        m = np.rot90(m,k=-1)
    else:
        m = np.array(list(fetch_sublists(arr, rep)))
        star_elements = np.flip(m[(m!=0).argmax(0), np.arange(m.shape[1])])
        m = m.T
    return m, star_elements


#Case 1 with right side orientation

mat, star = get_stars(arr_A, rep_A, 'right')

print('Matrix -')
print(mat)
print('')
print('Star elements -')
print(star)
 
 Matrix -
[[17 21  0  0  0]
 [18 22  0  0  0]
 [19 23 25  0  0]
 [20 24 26 27 28]]

Star elements -
[21 22 25 28]
 
 #Case 2 with left side orientation

mat, star = get_stars(arr_B, rep_B, 'left')

print('Matrix -')
print(mat)
print('')
print('Star elements -')
print(star)
 
 Matrix -
[[ 0  0 22]
 [ 0 18 23]
 [ 0 19 24]
 [ 0 20 25]
 [17 21 26]]

Star elements -
[17 20 19 18 22]
 

IIUC, вы пытаетесь разбить список на неравномерные фрагменты в качестве первой части. Обратите внимание, что вы не можете использовать numpy для хранения конечного массива, поскольку для него требуются одинаковые элементы в каждом объекте в каждом измерении, и здесь каждый из подсписков содержит разное количество элементов.

Вы можете использовать генераторы для этого как —

 def fetch_sublists(arr, rep):
    itr = iter(arr)
    for size in rep:
        sublist = []
        for _ in range(size):
            sublist.append(next(itr))
        yield sublist

print(list(fetch_sublists(arr_A, rep_A)))
print(list(fetch_sublists(arr_B, rep_B)))
 
 [[17, 18, 19, 20], [21, 22, 23, 24], [25, 26], [27], [28]]
[[17], [18, 19, 20, 21], [22, 23, 24, 25, 26]]
 

Неясно, что вы хотите после этого во второй части. Попросит вас уточнить это, чтобы я мог соответствующим образом обновить свой ответ.

Комментарии:

1. Уважаемый @Akshay Sehgal, спасибо за ваше решение, но я не собираюсь разделять список. Я просто пытаюсь извлечь некоторые значения из списка. Как показано на моем рисунке, я хочу сохранить числа со звездочкой. В сценарии A я хочу найти 21 , 22 , 25 и 28 . Эти числа можно найти с помощью using rep_A , но я не могу разработать для этого алгоритм. Я думаю, что предлагаемый код в моем сообщении вводит в заблуждение, но это была единственная неправильная вещь, которую я мог сделать.

2. Хм, так что особенного в 21, 22, 25 и 28? Почему эти числа? Почему вы не выбрали 27?

3. Дорогой @ Akshay Sehgal, это числа с правой стороны в сценарии A моего рисунка. Я думаю, используя rep_A = np.array([4,4,2,1,1]) , возможно, можно найти алгоритм для определения этих чисел. Я имею в виду, например, последние два числа rep_A ar одинаковы, поэтому я выбираю последнее. Затем от 1 до 2 изменяется уровень 1, поэтому для третьего столбца мы выбираем его первое значение. Также для 2-4 два шага меняются, поэтому должны быть извлечены первые два значения этого столбца. На моем рисунке это легче увидеть.

4. Я могу сказать, что сначала четыре значения создают один столбец, затем снова четыре создают другой столбец. следующий столбец создается двумя значениями, а последние два столбца создаются только одним значением. Я могу сказать, что это неровный список, и мне нужен край каждой строки в этом списке. Для сценария В тенденция иная. Частота чисел в столбце увеличивается.

5. Обновил мой ответ на основе ваших входных данных.