#python #python-3.x #numpy
#python #python-3.x #numpy
Вопрос:
У меня есть следующий массив numpy:
import numpy as np
a = np.array([2,15,66,180])
Теперь я хотел бы, чтобы разница между последовательными элементами (diff), деленная на 25, всегда была меньше или равна единице (diff / 25 < 0).
out = some_function(a,25)
out
[2,15,40,65,66,91,116,141,166,180]
Есть ли какой-нибудь интеллектуальный pythonic способ сделать это?
Комментарии:
1. Я не понимаю, какими должны быть эти дополнительные элементы в выходном массиве.
2. Почему число не после 40, 65? Итак, список должен быть 2,15,40, 65, 66….?
3. каким образом разница 40, 66/25 меньше 1?
Ответ №1:
Там могла бы пригодиться функция Numpy arange
, я бы сделал это следующим образом:
import numpy as np
a = np.array([2,15,66,180])
out = np.array([])
for i in range(len(a)-1):
out = np.hstack((out,np.arange(a[i],a[i 1],25)))
out = np.hstack((out,a[-1:]))
print(out)
вывод:
[ 2. 15. 40. 65. 66. 91. 116. 141. 166. 180.]
Это решение предполагает, что массив является плоским.
РЕДАКТИРОВАТЬ: Через некоторое время я заметил, что мое решение выдает np.array
of dtype float64
, то есть другой этот ввод — в зависимости от вашего использования это может быть проблемой, а может и не быть. Для случаев, когда это проблема, я переработал свой код в следующую форму:
import numpy as np
a = np.array([2,15,66,180])
print(a.dtype) #int64
out = np.hstack([np.arange(a[i],a[i 1],25) for i in range(len(a)-1)] [a[-1:]])
print(out) #[ 2 15 40 65 66 91 116 141 166 180]
print(out.dtype) #int64
Код также короче, но я оставил оригинальный, поскольку это может быть проще для понимания.
Комментарии:
1. Вау. Большое спасибо за этот отличный ответ!
Ответ №2:
Я сравнил методы @GGandalf и @Daweo. Интуитивно я ожидал, что arange
метод будет более производительным. Но на самом деле все наоборот. Решение GGandalf в 5 раз быстрее.
Не уверен, важно ли это для вашего варианта использования, но мне просто показалось интересным указать.
import timeit
setup_loop = """
import numpy as np
a = np.array([2,15,66,180])
def loop(a, step):
b = []
i = 0
x = a[i]
while i < a.size - 1:
if x >= a[i 1]:
i = 1
x = a[i]
b.append(x)
x = step
return b
"""
setup_array = """
import numpy as np
a = np.array([2,15,66,180])
def array(a, step):
out = np.array([])
for i in range(len(a) - 1):
out = np.hstack((out, np.arange(a[i], a[i 1], step)))
out = np.hstack((out, a[-1:]))
return out
"""
print(timeit.repeat("loop(a, 25)", setup_loop, number=100000, repeat=3))
print(timeit.repeat("array(a, 25)", setup_array, number=100000, repeat=3))
>>>[0.687177968943061, 0.6732553936845722, 0.6689018746795448]
>>>[3.5879034464852912, 3.6017167518256006, 3.5779435401398842]
Ответ №3:
Ну, не очень хорошая математика с массивами, но она работает путем увеличения счетчика. Я надеюсь, что это то, что вы имели в виду, потому что в своем вопросе вы указали, diff/25 < 0
что, вероятно, должно быть diff/25 <= 1
import numpy as np
a = np.array([2,15,66,180])
def some_function(a, step):
b = []
i = 0
x = a[i]
while i < a.size - 1:
if x >= a[i 1]:
i = 1
x = a[i]
b.append(x)
x = step
return b
print(some_function(a, 25))
>>> [2, 15, 40, 65, 66, 91, 116, 141, 166, 180]
Комментарии:
1. Хм … попробуй: [3, 15, 139, 287], вы можете видеть, что последняя запись потеряна
2. только что отредактировал код. Теперь он должен включать последний
3. Отлично! Большое спасибо за вашу помощь!