повторение отфильтрованного массива Numpy с сохранением информации об индексе - PullRequest
0 голосов
/ 07 февраля 2020

Я пытаюсь передать отфильтрованные значения из массива Numpy в функцию. Мне нужно передавать значения только выше определенного значения и их индексную позицию в массиве Numpy.

Я пытаюсь избежать перебора всего массива в пределах python, используя собственные системы фильтрации Numpys, Массивы, с которыми я имею дело, содержат в себе 20 тыс. значений, потенциально только очень немногие из них релевантны.

import numpy as np

somearray = np.array([1,2,3,4,5,6])
arrayindex = np.nonzero(somearray > 4)

for i in arrayindex:
    somefunction(arrayindex[0], somearray[arrayindex[0]])

Это приводило к ошибкам logi c, не способным обрабатывать несколько значений, что привело меня к тестированию. это через оператор печати, чтобы увидеть, что происходит.

for cell in arrayindex:
    print(f"index {cell}")
    print(f"data {somearray[cell]}")

Я ожидал вывод

index 4
data 5
index 5
data 6

Но вместо этого я получил

index [4 5]
data [5 6]

Я посмотрел с помощью различных методов для перебора numpy массивов таких и neditor, но, похоже, ни один из них не позволяет мне выполнять фильтрацию значений за пределами для l oop.

Есть ли решение моего затруднительного положения?

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

Спасибо.

Ответы [ 2 ]

0 голосов
/ 07 февраля 2020
import numpy as np
somearray = np.array([1,2,3,4,5,6])
arrayindex = [idx for idx, val in enumerate(somearray) if val > 4]

for i in range(0, len(arrayindex)):
    somefunction(arrayindex[i], somearray[arrayindex[i]])

for i in range(0, len(arrayindex)):
    print("index", arrayindex[i])
    print("data", somearray[arrayindex[i]])
0 голосов
/ 07 февраля 2020

Вам необходимо иметь четкое представление о том, что производит nonzero, и обратить внимание на разницу между индексацией списком (списками) и кортежем.

===

In [110]: somearray = np.array([1,2,3,4,5,6]) 
     ...: arrayindex = np.nonzero(somearray > 4)                                               

nonzero создает набор массивов, по одному на измерение (это становится более очевидным с 2d массивами):

In [111]: arrayindex                                                                           
Out[111]: (array([4, 5]),)

Это может использоваться непосредственно в качестве индекса:

In [113]: somearray[arrayindex]                                                                
Out[113]: array([5, 6])

В этом 1d-случае вы можете извлечь массив из кортежа и выполнить итерации по нему:

In [114]: for i in arrayindex[0]:print(i, somearray[i])                                        
4 5
5 6

argwhere делает 'transpose', который также может быть использован для итерации

In [115]: idxs = np.argwhere(somearray>4)                                                      
In [116]: idxs                                                                                 
Out[116]: 
array([[4],
       [5]])
In [117]: for i in idxs: print(i,somearray[i])                                                 
[4] [5]
[5] [6]

idxs - это (2,1) форма, поэтому i - это (1,) массив формы, в результате чего на дисплее отображаются скобки , Иногда это полезно, но nonzero используется чаще (часто под другим именем, np.where).

2d

argwhere имеет 2d пример:

In [119]: x=np.arange(6).reshape(2,3)                                                          
In [120]: np.argwhere(x>1)                                                                     
Out[120]: 
array([[0, 2],
       [1, 0],
       [1, 1],
       [1, 2]])
In [121]: np.nonzero(x>1)                                                                      
Out[121]: (array([0, 1, 1, 1]), array([2, 0, 1, 2]))
In [122]: x[np.nonzero(x>1)]                                                                   
Out[122]: array([2, 3, 4, 5])

Хотя nonzero можно использовать для индексации массива, элементы argwhere не могут.

In [123]: for ij in np.argwhere(x>1): 
     ...:     print(ij,x[ij]) 
     ...:                                                                                      
...
IndexError: index 2 is out of bounds for axis 0 with size 2

Проблема в том, что ij - это список, который используется для индексации по измерению. numpy различает списки и кортежи при индексации. (В более ранних версиях различие исчезло, но в текущих версиях используется более строгий подход.)

Поэтому нам нужно преобразовать список в кортеж. Один из способов - распаковать его:

In [124]: for i,j in np.argwhere(x>1): 
     ...:     print(i,j,x[i,j]) 
     ...:      
     ...:                                                                                      
0 2 2
1 0 3
1 1 4
1 2 5

Я мог бы использовать: print(ij,x[tuple(ij)]) в [123].

Я должен был использовать распаковку итерации [117]:

In [125]: for i, in idxs: print(i,somearray[i])                                                
4 5
5 6

или somearray[tuple(i)]

...