Запуск медианы значений y в диапазоне x
Ниже представлен график рассеяния, построенный из двух массивов numpy.
Пример графика рассеяния
![enter image description here]()
То, что я хотел бы добавить к этому сюжету, - это текущая медиана y в диапазоне x. Я привел пример в Photoshop:
Измененный график рассеяния
![enter image description here]()
В частности, мне нужна медиана для точек данных в ячейках по 1 единице вдоль оси х между двумя значениями (этот диапазон будет варьироваться в зависимости от многих графиков, но я могу вручную отрегулировать его). Я ценю любые советы, которые могут указывать на меня в правильном направлении.
Ответы
Ответ 1
Я бы использовал np.digitize
, чтобы выполнить сортировку bin для вас. Таким образом, вы можете легко применить любую функцию и задать интересующий вас диапазон.
import numpy as np
import pylab as plt
N = 2000
total_bins = 10
# Sample data
X = np.random.random(size=N)*10
Y = X**2 + np.random.random(size=N)*X*10
bins = np.linspace(X.min(),X.max(), total_bins)
delta = bins[1]-bins[0]
idx = np.digitize(X,bins)
running_median = [np.median(Y[idx==k]) for k in range(total_bins)]
plt.scatter(X,Y,color='k',alpha=.2,s=2)
plt.plot(bins-delta/2,running_median,'r--',lw=4,alpha=.8)
plt.axis('tight')
plt.show()
![enter image description here]()
В качестве примера универсальности метода добавьте ошибки, заданные стандартным отклонением каждого бина:
running_std = [Y[idx==k].std() for k in range(total_bins)]
plt.errorbar(bins-delta/2,running_median,
running_std,fmt=None)
![enter image description here]()
Ответ 2
Эта проблема также может быть эффективно решена с помощью python pandas (Библиотека анализа данных Python), которая предлагает собственные методы резки и анализа данных,
Рассмотрим это
(Kudos и +1 to @Hooked для своего примера, из которого я взял данные X
и Y
)
import pandas as pd
df = pd.DataFrame({'X' : X, 'Y' : Y}) #we build a dataframe from the data
data_cut = pd.cut(df.X,bins) #we cut the data following the bins
grp = df.groupby(by = data_cut) #we group the data by the cut
ret = grp.aggregate(np.median) #we produce an aggregate representation (median) of each bin
#plotting
plt.scatter(df.X,df.Y,color='k',alpha=.2,s=2)
plt.plot(ret.X,ret.Y,'r--',lw=4,alpha=.8)
plt.show()
Примечание: здесь значения x красной кривой являются би-му-х-медианами (можно использовать средние точки бункеров).
![enter image description here]()
Ответ 3
Вы можете создать функцию на основе numpy.median()
, которая будет вычислять медианное значение с учетом интервалов:
import numpy as np
def medians(x, y, intervals):
out = []
for xmin, xmax in intervals:
mask = (x >= xmin) & (x < xmax)
out.append(np.median(y[mask]))
return np.array(out)
Затем используйте эту функцию для требуемых интервалов:
import matplotlib.pyplot as plt
intervals = ((18, 19), (19, 20), (20, 21), (21, 22))
centers = [(xmin+xmax)/2. for xmin, xmax in intervals]
plt.plot(centers, medians(x, y, intervals)
Ответ 4
Я написал что-то вроде этого в C#
. Я не делаю Python, поэтому вот псевдокод:
- создать
List
для использования для данных, которые медиана будет выведена из
- сортировать точки разброса по площади
x
значение
- цикл через отсортированные точки
x
значение
- для каждой точки вставить значение
Y
этой точки в медианный список, чтобы средний список увеличивался как отсортированный список. то есть вставить Y, поэтому значение списка выше и ниже этого равно > и < это соответственно. Взгляните сюда: Вставка значений в определенные места в списке в Python.
- после добавления каждого значения
Y
, медианное значение будет значением списка в текущем среднем индексе, т.е. List(List.Length/2)
Надеюсь, что это поможет!