#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:
Основываясь на ваших комментариях и разъяснениях, вот способ, которым вы можете решить эту проблему.
Как это работает —
fetch_sublists()
генератор разбивает список наsublists
и передpads
каждым с 0s.get_stars()
вызывает приведенное вышеgenerator
для построения матрицы поstacking
массивам, переворачивает нули вверхorientation
и сохраняет их вm
- Использует эту ориентацию для поиска первых ненулевых элементов из верхнего направления и сохраняет его в
star
- Поворачивает матрицу в нужном направлении и перезаписывает ее на
m
- Наконец, возвращает как матрицу, так
mat
и побочные элементы asstar
.
#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
. Эти числа можно найти с помощью usingrep_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. Обновил мой ответ на основе ваших входных данных.