Я знаю, что повторение массивов numpy обходится дороже, чем использование функций numpy. Это очень важно для меня, так как мои массивы довольно большие.
Пожалуйста, используйте предоставленный код в качестве объяснения того, чего я хочу достичь
start_value = 12
start_arr = np.array([-2, -4, -60, -0.5, 2, 2, 1, 70, -2, -5, 2])
out_arr = []
ans = start_value
for i in start_arr:
if i > 0:
out_arr.append(i)
ans = i
else:
out_arr.append(ans)
out_arr = np.array(out_arr)
# [12, 12, 12, 12, 2, 2, 1, 70, 70, 70, 2]
Я не знаю, как сказать numpy использовать «ранее» присвоенное значение в случае i <= 0
. Также я не могу объяснить проблему поисковой системе моего браузера так, чтобы она выдавала что-то полезное.
У Pandas есть ffill
для таких вещей.
Использование панд:
import pandas as pd
out_arr = (pd.Series(start_arr).where(start_arr>0)
.ffill().fillna(start_value, downcast='infer').to_numpy()
)
Выход:
array([12, 12, 12, 12, 2, 2, 1, 70, 70, 70, 2])
Подход numpy (вдохновленный этим ответом):
a = np.r_[start_value, start_arr]
# array([ 12. , -2. , -4. , -60. , -0.5, 2. , 2. , 1. , 70. ,
# -2. , -5. , 2. ])
idx = np.maximum.accumulate(np.where(a>0, np.arange(a.shape[0]), 0))
# array([ 0, 0, 0, 0, 0, 5, 6, 7, 8, 8, 8, 11])
out_arr = a[idx][1:]
# array([12., 12., 12., 12., 2., 2., 1., 70., 70., 70., 2.])
Вот мое решение, использующее только Numpy (измените 12 на все, что хотите):
'''
импортировать numpy как np
массив = np.массив ([-2, -4, -60, -0,5, 2, 2, 1, 70, -2, -5, 2])
замена = 12
пока верно:
Ind = np.argmax(array<= 0)
if Ind>0 or replacement == 12:
if replacement == 12:
array[Ind] = replacement
replacement = None
else:
array[Ind] = array[Ind-1]
else:
break
'''
Спасибо за ваше предложение, но цикл while не улучшает производительность и по-прежнему итеративно строит массив.
Во-первых, вы делаете итерацию, но с функцией Numpy, как вы просили. Во-вторых, вы не строите массив заново, а заменяете только элементы, оптимизированные для памяти.
Вы можете создать массив исходного индекса для каждого значения в выходном массиве. Исходный индекс — это индекс предыдущего положительного значения. Вы можете вычислить их с помощью функции numpy.maximum.accumulate
после обнуления индексов отрицательных позиций.
После этого ведущие отрицательные элементы могут быть обработаны отдельно.
import numpy as np
start_value = 12
start_arr = np.array([-2, -4, -60, -0.5, 2, 2, 1, 70, -2, -5, 2])
source = np.arange(start_arr.size) # all indices
source[start_arr <= 0] = 0 # zero out negatives
out_arr = start_arr[np.maximum.accumulate(source)] # assign from source
out_arr[out_arr<=0] = start_value # leading negatives
print(out_arr)
# [12. 12. 12. 12. 2. 2. 1. 70. 70. 70. 2.]
Вы можете обобщить логику в нескольких словах?