Как связать 2D-данные вдоль оси X с Python - PullRequest
0 голосов
/ 01 июня 2018

У меня есть два массива соответствующих данных (x и y), которые я строю, как указано выше, на графике log-log.Данные в настоящее время слишком гранулированы, и я хотел бы их связать, чтобы получить более гладкие отношения.Могу ли я получить некоторые рекомендации о том, как я могу складывать вдоль оси x, в экспоненциальных размерах ячеек, чтобы они выглядели линейными в масштабе журнала?

Например, еслипервый бин имеет диапазон от x = 10 ^ 0 до 10 ^ 1, я хочу собрать все y-значения с соответствующими x в этом диапазоне и усреднить их в одно значение для этого бина.Я не думаю, что np.hist или plt.hist вполне справляются с задачей, так как они выполняют биннинг, подсчитывая вхождения.

Редактировать: Для контекста, если это помогает, приведенный выше график является графиком ассортимента, который отображаетв той или иной степени определенной сети.

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Вы можете использовать scipy.stats.binned_statistic, чтобы получить среднее значение данных в каждом бине.Бункеры лучше всего создавать через numpy.logspace.Затем вы можете отобразить эти средства, например, как горизонтальные линии, охватывающие ширину бункера, или как разброс в средней позиции.

import numpy as np; np.random.seed(42)
from scipy.stats import binned_statistic
import matplotlib.pyplot as plt

x = np.logspace(0,5,300)
y = np.logspace(0,5,300)+np.random.rand(300)*1.e3


fig, ax = plt.subplots()
ax.scatter(x,y, s=9)

s, edges, _ = binned_statistic(x,y, statistic='mean', bins=np.logspace(0,5,6))

ys = np.repeat(s,2)
xs = np.repeat(edges,2)[1:-1]
ax.hlines(s,edges[:-1],edges[1:], color="crimson", )

for e in edges:
    ax.axvline(e, color="grey", linestyle="--")

ax.scatter(edges[:-1]+np.diff(edges)/2, s, c="limegreen", zorder=3)

ax.set_xscale("log")
ax.set_yscale("log")
plt.show()

enter image description here

0 голосов
/ 01 июня 2018

Вы можете достичь этого с пандами.Идея состоит в том, чтобы присвоить каждому значению X интервал, используя np.digitize.Поскольку вы используете логарифмическую шкалу, имеет смысл использовать np.logspace для выбора интервалов экспоненциально изменяющихся длин.Наконец, вы можете группировать значения X в каждом интервале и вычислять средние значения Y.


import pandas as pd
import numpy as np

x_max = 10

xs = np.exp(x_max * np.random.rand(1000))
ys = np.exp(np.random.rand(1000))

df = pd.DataFrame({
    'X': xs,
    'Y': ys,
})

df['Xbins'] = np.digitize(df.X, np.logspace(0, x_max, 30, base=np.exp(1)))
df['Ymean'] = df.groupby('Xbins').Y.transform('mean')
df.plot(kind='scatter', x='X', y='Ymean')
...