Я хотел бы рассчитать взвешенную медиану каждой строки кадра данных панд.
Я нашел эту замечательную функцию (https://stackoverflow.com/a/29677616/10588967),, но мне кажется, что я не могу передать 2d массив.
def weighted_quantile(values, quantiles, sample_weight=None, values_sorted=False, old_style=False):
""" Very close to numpy.percentile, but supports weights.
NOTE: quantiles should be in [0, 1]!
:param values: numpy.array with data
:param quantiles: array-like with many quantiles needed
:param sample_weight: array-like of the same length as `array`
:param values_sorted: bool, if True, then will avoid sorting of initial array
:param old_style: if True, will correct output to be consistent with numpy.percentile.
:return: numpy.array with computed quantiles.
"""
values = numpy.array(values)
quantiles = numpy.array(quantiles)
if sample_weight is None:
sample_weight = numpy.ones(len(values))
sample_weight = numpy.array(sample_weight)
assert numpy.all(quantiles >= 0) and numpy.all(quantiles <= 1), 'quantiles should be in [0, 1]'
if not values_sorted:
sorter = numpy.argsort(values)
values = values[sorter]
sample_weight = sample_weight[sorter]
weighted_quantiles = numpy.cumsum(sample_weight) - 0.5 * sample_weight
if old_style:
# To be convenient with numpy.percentile
weighted_quantiles -= weighted_quantiles[0]
weighted_quantiles /= weighted_quantiles[-1]
else:
weighted_quantiles /= numpy.sum(sample_weight)
return numpy.interp(quantiles, weighted_quantiles, values)
Используя код из ссылки, работает следующее:
weighted_quantile([1, 2, 9, 3.2, 4], [0.0, 0.5, 1.])
Однако это не работает:
values = numpy.random.randn(10,5)
quantiles = [0.0, 0.5, 1.]
sample_weight = numpy.random.randn(10,5)
weighted_quantile(values, quantiles, sample_weight)
Я получаю следующую ошибку:
weighted_quantiles = np.cumsum(sample_weight) - 0.5 * sample_weight
ValueError: операнды не могут передаваться вместе с фигурами (250,) (10,5,5)
Вопрос
Можно ли применить эту взвешенную квантильную функцию в векторизованном виде к кадру данных, или я могу добиться этого только с помощью .apply ()?
Большое спасибо за ваше время!