группирование двух numy ndarrays в определенных диапазонах одного и вычисление среднего значения и распределения другого в этом диапазоне - PullRequest
0 голосов
/ 01 октября 2019

Я не уверен, правильно ли я задаю вопрос, но рассмотрим два ndarrays x и y:

import numpy as np
import matplotlib.pyplot as plt

N = 1000
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N)
y = np.sin(2.0 * np.pi * x) + 0.5 * np.sin(3 * 2.0 * np.pi * x) \
    + 0.1 * np.random.uniform(-1.0, 1.0, N)
plt.plot(x, y)
plt.show()
                 <img src="https://i.stack.imgur.com/TdbPh.png" width="400">               

, теперь рассмотрим x_2 как

M = 10
x_2 = np.linspace(0.0, N*T, N//M)

вид группировки x в диапазоны с длиной M. Теперь я хочу иметь y_m и y_v в следующем псевдокоде:

y_m = average of `y`es for x_2_(i-1) < x < x_2_(i)
y_v = variance of `y`es for x_2_(i-1) < x < x_2_(i)

для i в диапазоне 0 < i < N / M. Конечно, я мог бы определить некоторые циклы for, но, учитывая, что мой набор данных огромен, я ищу более векторизованный способ с использованием функциональных возможностей. Также, пожалуйста, учтите, что имеющиеся у меня ndarrays не отсортированы.

PS Меня попросили реализовать способ, который я знаю:

M = 10
x_2 = np.linspace(x.min(), x.max(), N//M)

y_m = np.zeros(N // M - 1)
y_v = np.zeros(N // M - 1)
for ii in range(N // M - 1):
    y_m[ii] = y[((x_2[ii] <= x) & (x < x_2[ii+1]))].mean()
    y_v[ii] = np.var(y[((x_2[ii] <= x) & (x < x_2[ii+1]))])

plt.plot(x, y)
plt.plot(x_2[:-1], y_m)
plt.show()
              <img src="https://i.stack.imgur.com/DX9Hk.png" width="400">               

PS2. Одной из идей может быть сортировкаzip (x, y) в соответствии с x, затем измените форму ndarray и затем вычислите среднее значение и дисперсию конкретной оси.

1 Ответ

0 голосов
/ 11 октября 2019

Итак, я получил возможность реализовать идею, предложенную мной в PS2. в исходном сообщении, используя функцию reshape numpy:

MM = 10
x_2 = np.linspace(x.min(), x.max(), N // MM)

z = y[(N % MM):].reshape(((N - (N % MM)) // MM, MM))
y_m = z.mean(axis=1)
y_v = z.var(axis=1)

plt.fill_between(x_2, y_m - 100 * y_v / 2, y_m + 100 * y_v / 2, color="blue")
plt.plot(x_2, y_m, color="red")

, в результате:

                <img src="https://i.stack.imgur.com/RRfVl.png" width="400">               

Теперь эта реализация имеет два основных недостатка, которые заключаются в том, что предполагается, что данные x равномерно распределены и отсортированы, что не всегда так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...