Так что я думаю, что это близко к тому, что вы ищете.
Импорт библиотек и подделка некоторых искаженных данных.Здесь, поскольку входные данные неизвестного происхождения, я создал искаженные данные, используя np.expm1(np.random.normal())
.Вы также можете использовать skewnorm().rvs()
, но это обман, поскольку вы также будете использовать его для определения характеристик.
Я сглаживаю необработанные образцы, чтобы упростить построение гистограмм.
import numpy as np
from scipy.stats import skewnorm
# generate dummy raw starting data
# smaller shape just for simplicity
shape = (100, 100)
raw_skewed = np.maximum(0.0, np.expm1(np.random.normal(2, 0.75, shape))).astype('uint16')
# flatten to look at histograms and compare distributions
raw_skewed = raw_skewed.reshape((-1))
Теперь найдите параметры, которые характеризуют ваши искаженные данные, и используйте их, чтобы создать новый дистрибутив для выборки, который, как мы надеемся, хорошо соответствует вашим исходным данным.
Эти две строки кода действительно то, что выпосле того, как я думаю.
# find params
a, loc, scale = skewnorm.fit(raw_skewed)
# mimick orig distribution with skewnorm
new_samples = skewnorm(a, loc, scale).rvs(10000).astype('uint16')
Теперь нарисуйте распределения каждого из них для сравнения.
plt.hist(raw_skewed, bins=np.linspace(0, 60, 30), hatch='\\', label='raw skewed')
plt.hist(new_samples, bins=np.linspace(0, 60, 30), alpha=0.65, color='green', label='mimic skewed dist')
plt.legend()
Гистограммы довольно близки.Если это выглядит достаточно хорошо, измените ваши новые данные в нужную форму.
# final result
new_samples.reshape(shape)
Теперь ... вот где я думаю, что это, вероятно, не дотягивает.Посмотрите на тепловую карту каждого.Первоначальный дистрибутив имел более длинный хвост справа (больше выбросов, которые skewnorm()
не характеризовали).
На этом графике показана тепловая карта каждого.
# plot heatmaps of each
fig = plt.figure(2, figsize=(18,9))
ax1 = fig.add_subplot(1, 2, 1)
ax2 = fig.add_subplot(1, 2, 2)
im1 = ax1.imshow(raw_skewed.reshape(shape), vmin=0, vmax=120)
ax1.set_title("raw data - mean: {:3.2f}, std dev: {:3.2f}".format(np.mean(raw_skewed), np.std(raw_skewed)), fontsize=20)
im2 = ax2.imshow(new_samples.reshape(shape), vmin=0, vmax=120)
ax2.set_title("mimicked data - mean: {:3.2f}, std dev: {:3.2f}".format(np.mean(new_samples), np.std(new_samples)), fontsize=20)
plt.tight_layout()
# add colorbar
fig.subplots_adjust(right=0.85)
cbar_ax = fig.add_axes([0.88, 0.1, 0.08, 0.8]) # [left, bottom, width, height]
fig.colorbar(im1, cax=cbar_ax)
Глядя на это ..... вы можете видеть случайные желтые пятна, указывающие на очень высокие значения в исходном распределении, которые не попали в вывод.Это также проявляется в более высоком стандартном отклонении входных данных (см. Заголовки в каждой тепловой карте, но, опять же, как в комментариях к исходному вопросу ... имеется ввиду, что & std на самом деле не характеризует распределения, поскольку они не являются нормальными).... но они в качестве относительного сравнения).
Но ... в этом-то и заключается проблема, связанная с очень специфическим искаженным образцом, который я создал для начала.Надеюсь, здесь достаточно, чтобы возиться и настраиваться, пока не будет соответствовать вашим потребностям и конкретному набору данных.Удачи!