обработка списка python numpy

#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. Отлично! Большое спасибо за вашу помощь!