Как избежать итеративного построения массива numpy

Я знаю, что повторение массивов 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. Также я не могу объяснить проблему поисковой системе моего браузера так, чтобы она выдавала что-то полезное.

Вы можете обобщить логику в нескольких словах?

mozway 04.04.2023 15:38

У Pandas есть ffill для таких вещей.

user2357112 04.04.2023 15:42
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
56
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Использование панд:

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 не улучшает производительность и по-прежнему итеративно строит массив.

Tarquinius 05.04.2023 09:39

Во-первых, вы делаете итерацию, но с функцией Numpy, как вы просили. Во-вторых, вы не строите массив заново, а заменяете только элементы, оптимизированные для памяти.

Reza Besharat 06.04.2023 10:26
Ответ принят как подходящий

Вы можете создать массив исходного индекса для каждого значения в выходном массиве. Исходный индекс — это индекс предыдущего положительного значения. Вы можете вычислить их с помощью функции 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.]

Другие вопросы по теме