У меня есть массив numpy с положительными и отрицательными величинами в.
a = array([1,1,-1,-2,-3,4,5])
Я хочу создать другой массив, который содержит значение в каждом индексе, где изменение знака происходит (Например, если элемент тока положителен, и предыдущий элемент отрицателен и наоборот).
Для массива выше, я ожидал бы получать следующий результат
array([0,0,1,0,0,1,0])
С другой стороны, список положений в массиве, где изменения знака происходят или список булевских переменных вместо 0 и 1's, прекрасен.
Что-то вроде
a = array([1,1,-1,-2,-3,4,5])
asign = np.sign(a)
signchange = ((np.roll(asign, 1) - asign) != 0).astype(int)
print signchange
array([0, 0, 1, 0, 0, 1, 0])
Теперь numpy.roll выполняет циклический сдвиг, поэтому, если последний элемент имеет другой знак, чем Во-первых, первым элементом в массиве смены знака будет 1. Если это нежелательно, можно, конечно, сделать простое
signchange[0] = 0
. Кроме того, np.sign считает, что 0 имеет собственный знак, отличный от положительных или отрицательных значений. Например. массив «signchange» для [-1,0,1] будет [0,1,1], даже если нулевая линия была «пересечена» только один раз. Если это нежелательно, в первом примере можно вставить строки
sz = asign == 0
while sz.any():
asign[sz] = np.roll(asign, 1)[sz]
sz = asign == 0
между строками 2 и 3.
В приведенных выше ответах используется понимание списка и некоторая магия numpy для получения желаемого результата. Вот очень простой, хотя и немного запутанный способ сделать то же самое:
import numpy as np
arr = np.array([1,1,-1,-2,-3,4,5])
result = []
for i, v in enumerate(arr):
if i == 0:
change = False
elif v < 0 and arr[i-1] > 0:
change = True
elif v > 0 and arr[i-1] < 0:
change = True
else:
change = False
result.append(change)
print result
Для прямой интерпретации этого вопроса, когда нули не являются их собственным регистром, вероятно, проще использовать больше
, чем знак
. Вот пример:
a = array([1, 1, -1, -2, -3, 0, 4, 0, 5, 6])
x = greater_equal(a, 0)
sign_change = x[:-1]-x[1:]
Что дает при печати с помощью T
или F
, чтобы указать изменение знака между разными числами:
1 F 1 T -1 F -2 F -3 T 0 F 4 F 0 F 5 F 6
при печати с использованием:
print `a[0]`+"".join([(" T" if sign_change[i] else " F")+" "+`a[i+1]` for i in range(len(sign_change))])
Также обратите внимание, что это на один элемент короче исходного массива, что имеет смысл, поскольку вы просите изменить знак. Если вы хотите включить изменение между последним и первым элементом, вы можете использовать roll
, как предлагали другие.
Как насчет
[0 if x == 0 else 1 if numpy.sign(a[x-1]) != numpy.sign(y) else 0 for x, y in enumerate(a)]
numpy.sign присваивает 0 свой собственный знак, поэтому нули будут заменять знак любого, кроме других нулей, что, вероятно, именно то, что вы хотите .