Вставьте элементы в массив NumPy так, чтобы минимальный интервал был произвольным - PullRequest
0 голосов
/ 12 октября 2018

Учитывая упорядоченный массив numpy чисел с плавающей запятой (от минимальной до максимальной), я должен убедиться, что расстояние между элементами меньше произвольного числа с плавающей запятой, которое я называю step.

Это мой код инасколько я вижу, это работает, но мне интересно, есть ли более элегантный способ сделать это:

import numpy as np

def slpitArr(arr, step=3.):
    """
    Insert extra elements into array so that the maximum spacing between
    elements is 'step'.
    """
    # Keep going until no more elements need to be added
    while True:
        flagExit = True
        for i, v in enumerate(arr):
            # Catch last element in list
            try:
                if abs(arr[i + 1] - v) > step:
                    new_v = (arr[i + 1] + v) / 2.
                    flagExit = False
                    break
            except IndexError:
                pass
        if flagExit:
            break
        # Insert new element
        arr = np.insert(arr, i + 1, new_v)

    return arr


aa = np.array([10.08, 14.23, 19.47, 21.855, 24.34, 25.02])

print(aa)
print(slpitArr(aa))

, что приводит к:

[10.08  14.23  19.47  21.855 24.34  25.02 ]
[10.08  12.155 14.23  16.85  19.47  21.855 24.34  25.02 ]

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Вот однопроходное решение, в котором

1) вычисляет разницу d между последовательными точками

2) делит потолок d шаг за шагом, чтобы получить m

2a), необязательно, округляет m до ближайшей степени двух

3) делит d на м и повторяет результат м раз

4) образует совокупную сумму

Вот код.Техническое примечание: первый элемент d - это не разница, а «якорь», поэтому он равен первому элементу данных.

def fill(data, step, force_power_of_two=True):
    d = data.copy()
    d[1:] -= data[:-1]
    if force_power_of_two:
        m = 1 << (np.frexp(np.nextafter(d / step, -1))[1]).clip(0, None)
    else:
        m = -(d // -step).astype(int)
    m[0] = 1
    d /= m
    return np.cumsum(d.repeat(m))

Пример выполнения:

>>> inp
array([10.08 , 14.23 , 19.47 , 21.855, 24.34 , 25.02 ])
>>> fill(inp, 3)
array([10.08 , 12.155, 14.23 , 16.85 , 19.47 , 21.855, 24.34 , 25.02 ])
0 голосов
/ 12 октября 2018

Для заказанных массивов:

def slpitArr(arr, step=3.):
    d = np.ediff1d(arr)
    n = (d / step).astype(dtype=np.int)
    idx = np.flatnonzero(n)
    indices = np.repeat(idx, n[idx]) + 1
    values = np.concatenate(
        [np.linspace(s1, s2, i+1, False)[1:] for s1, s2, i in zip(arr[:-1], arr[1:], n)])
    return np.insert(arr, indices, values)

Тогда

>>> aa = np.array([10.08, 14.23, 19.47, 21.855, 24.34, 25.02])
>>> print(slpitArr(aa))
[10.08  12.155 14.23  16.85  19.47  21.855 24.34  25.02 ]

>>> print(slpitArr(aa, 2.5))
[10.08       12.155      14.23       15.97666667 17.72333333 19.47
 21.855      24.34       25.02      ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...