Я работаю над новым стандартным классом гистограмм для Python (в идеале, чтобы способствовать NumPy, учитывая многочисленные серьезные недостатки, которые я испытал при использовании стандартной реализации при выполнении оценки плотности во время моего Masters).
Я разработалрешение, которое, как я считаю, гораздо более аккуратное и более универсальное для организации бинов переменного размера, но, к сожалению, я изо всех сил пытаюсь выполнить основной пункт гистограммы - суммирование количества записей в бине - надежным способом.Ниже я приведу упрощенную упрощенную версию.
В примере кода, который успешно суммирует количество точек в каждой ячейке, вы можете запустить нижеприведенную диаграмму, которая также создает график, подобный следующему:
График простых бинов
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.patches as patches
class Custom_Histogram():
def __init__(self, df, bins=None):
self.DF = df
self.bins = np.array(bins)
self.n_dims = len(df.columns.values)
## Count number of datapoints in each bin
self.hist = np.array([
np.sum( (self.DF.iloc[:,:] >= self.bins[:,:,0][i][:]) &
(self.DF.iloc[:,:] < self.bins[:,:,1][i][:])
)
for i in range(len(self.bins)) ], dtype=np.int32)[:,0]
## Generate Random Data
N = 200
X = np.random.normal(0.5,0.15,N)
Y = np.random.normal(0.5,0.05,N)
## Populate a Pandas DataFrame
DF = pd.DataFrame({'x':X,'y':Y})
## Hardcoded, contiguous, 2D variable-area bins
bins = np.array([
[[0.0,0.2],[0.0,1.5]],
[[0.2,0.4],[0.0,1.5]],
[[0.4,0.6],[0.0,1.5]],
[[0.6,0.8],[0.0,1.5]],
[[0.8,1.0],[0.0,1.5]]
])
## Generate histogram using custom bins
Hist = Custom_Histogram(DF, bins)
print('Histogram: ', Hist.hist)
## 2D Plot
fig, axes = plt.subplots(figsize=(4, 3.5))
plt.scatter(DF.iloc[:,0], DF.iloc[:,1], 5, 'k')
# Create a patch for each bin and plot
for i,bin in enumerate(bins):
rect = patches.Rectangle( (bin[0][0],bin[1][0]),
bin[0][1]-bin[0][0],
bin[1][1]-bin[1][0],
linewidth=1,
edgecolor='r',facecolor='none')
axes.add_patch(rect)
axes.set_ylim(-0.5,2)
axes.set_xlim(-0.5,1.5)
print('Histogram Sum: ', np.sum(Hist.hist))
print('Data Points: ', N)
plt.show()
С более сложными бинами количество точек больше не является правильным, а некоторые, кажется, считаются дважды.Попытка с ячейками:
bins = np.array([
[[0.0,0.2],[0.0,1.5]],
[[0.2,0.4],[0.0,1.5]],
[[0.4,0.6],[0.0,1.0]],
[[0.4,0.6],[1.0,1.5]],
[[0.6,0.8],[0.0,0.5]],
[[0.6,0.8],[0.5,1.5]],
[[0.8,1.0],[0.0,1.5]]
])
, которая строится как: Сложная ячейка с ячейками , возвращает больше точек, чем существует.
Поэтому я хотел бы знать, как изменитьлогика заключается в подсчете точек данных, но сохранении их эффективным векторным способом (я убежден, что здесь нет необходимости в каких-либо циклах).Мне также нужно, чтобы это охватывало разные измерения, что, кажется, уже почти работает (структура срезов правильно выполняет условие в каждом измерении, но происходит что-то еще, что вызывает тот же тип двойного счета, что и выше).