2016-06-27 2 views
1

Мне интересно, есть ли хороший способ использовать инструкцию if-else внутри фигурных скобок массива в Python для назначения значений. Я хотел бы что-то вроде:Можете ли вы использовать инструкцию if-else внутри фигурных скобок для массива в Python?

A = #some 2D array of length m by n, already initialized 
A = np.float64(A) 
val = someValue #any number, pick a number 

A = [[val for j in range(n) if A[i][j] < val, else A[i][j]=A[i][j]] for i in range(m)] 

Есть ли хороший способ сделать это? Альтернативно, если numpy имеет более быстрый способ вычислить это, это будет одинаково хорошо, если не лучше.

Чем дольше способ сделать то, что я пытаюсь добиться будет что-то вроде

for i in range(m): 
    for j in range(n): 
     if A[i][j] < val: 
      A[i][j] = val 

Нужный выход устанавливать какие-либо значения ниже порога до этого порога. Я могу сделать более простые if-утверждения с 1D-массивом, такие как

myArray = [otherArray[i] for i in range(theRange) if otherArray[i]>=value and otherArray[i]<=anotherValue] 

Этот пример 1D не то, что я хочу. Это всего лишь пример типа кодирующего блока, который я ищу. Кажется, что он быстрее обрабатывает традиционные инструкции if-else. одна линия синтаксис троичный оператор

+1

Что вы ожидаемый результат? Вы можете использовать условное выражение *, но не так, как вы это делаете (например, вы не можете выполнять назначения внутри выражений). Мне совершенно непонятно, чего вы пытаетесь достичь здесь. –

+0

@MartijnPieters Я только что пересмотрел свой вопрос. – Lou

+4

'A [A

ответ

5

С массивными массивами мы стараемся избегать итераций (понимание списка). Иногда это необходимо, но в данном случае это не так:

In [403]: A=np.arange(16).reshape(4,4)  
In [404]: A1=A.astype(np.float64) # better syntax for converting to float 

In [405]: A1 
Out[405]: 
array([[ 0., 1., 2., 3.], 
     [ 4., 5., 6., 7.], 
     [ 8., 9., 10., 11.], 
     [ 12., 13., 14., 15.]]) 

Логический массив, который показывает, где тест True/False:

In [406]: A1<5 
Out[406]: 
array([[ True, True, True, True], 
     [ True, False, False, False], 
     [False, False, False, False], 
     [False, False, False, False]], dtype=bool) 

Мы можем индексировать с такой маской:

In [407]: A1[A1<5]=5 

In [408]: A1 
Out[408]: 
array([[ 5., 5., 5., 5.], 
     [ 5., 5., 6., 7.], 
     [ 8., 9., 10., 11.], 
     [ 12., 13., 14., 15.]]) 

np.wherenp.nonzero) возвращает индексы, в которых условие истинно; where имеет версию, которая работает как оператор троичного (по каждому элементу):

In [410]: np.where(A<5,5,A) 
Out[410]: 
array([[ 5, 5, 5, 5], 
     [ 5, 5, 6, 7], 
     [ 8, 9, 10, 11], 
     [12, 13, 14, 15]]) 

Мы можем также clip с np.maximum:

In [411]: np.maximum(A,5) 
Out[411]: 
array([[ 5, 5, 5, 5], 
     [ 5, 5, 6, 7], 
     [ 8, 9, 10, 11], 
     [12, 13, 14, 15]]) 

In [417]: A.clip(5,None) 
Out[417]: 
array([[ 5, 5, 5, 5], 
     [ 5, 5, 6, 7], 
     [ 8, 9, 10, 11], 
     [12, 13, 14, 15]]) 
+0

Отличные примеры, и вы можете выполнять множество условий, таких как np.where ((A < 3) | (A > 10), np.nan, A), но мне еще предстоит найти простой способ определения, где A может быть «в» списке значений т.е. [3, 5, 9, 12, 2], не прибегая к уплощению, используя список. затем переформатирование. Есть ли расширение для любого из вышеперечисленного, например, где, что эквивалентно «сравнениям»? –

2

Python выглядит следующим образом

variable = a if CONDITION else b 

Вы можете поместить это внутри списка понимания, как хорошо. Непонятно, что в вашем примере val, но я предполагаю, что это значение, которое вы указали заранее.

val = 2 
A = [[val if A[i][j] < val else A[i][j] for j in range(n)] for i in range(m)] 
+0

Это сработало незаметно! После этого мне пришлось преобразовать тип обратно в np.float64.В противном случае он сделал именно то, что хотел. – Lou

+2

Поскольку 'A' - это массив, более понятно, если вы используете' A [i, j] 'для индексации элемента. – hpaulj

Смежные вопросы