Пытаясь расширить этот вопрос об использовании средневзвешенных значений в groupby
объектах, я намереваюсь aggregate
двух функций на объекте groupby
, одна из которых работает на двух столбцах groupby
объект и один в одном столбце.
Использование набора данных seaborn anscombe
в качестве базы, где x
будет наблюдениями и y
неопределенностями, которые будут использоваться для расчета весов как 1/y**2
:
дает
weighted_averages
Out[558]:
dataset
I 7.491303
II 6.794108
III 7.846522
IV 8.307357
dtype: float64
uncertainties
Out[559]:
dataset
I 2.009329
II 1.869217
III 2.102733
IV 2.089466
dtype: float64
Однако при объединении двух функций используется метод agg
, как описано
здесь combined = anscombe.groupby(by='dataset').agg([weighted_average, reverse_sumsquares])
Я получаю
combined = anscombe.groupby(by='dataset').agg([weighted_average, reverse_sumsquares])
Traceback (most recent call last):
File "/anaconda3/lib/python3.7/site-packages/pandas/core/groupby/generic.py", line 265, in aggregate
return self._python_agg_general(func, *args, **kwargs)
File "/anaconda3/lib/python3.7/site-packages/pandas/core/groupby/groupby.py", line 926, in _python_agg_general
result, counts = self.grouper.agg_series(obj, f)
File "/anaconda3/lib/python3.7/site-packages/pandas/core/groupby/ops.py", line 641, in agg_series
return self._aggregate_series_fast(obj, func)
File "/anaconda3/lib/python3.7/site-packages/pandas/core/groupby/ops.py", line 666, in _aggregate_series_fast
result, counts = grouper.get_result()
File "pandas/_libs/reduction.pyx", line 378, in pandas._libs.reduction.SeriesGrouper.get_result
File "pandas/_libs/reduction.pyx", line 195, in pandas._libs.reduction._BaseGrouper._apply_to_group
File "/anaconda3/lib/python3.7/site-packages/pandas/core/groupby/groupby.py", line 913, in <lambda>
f = lambda x: func(x, *args, **kwargs)
File "<ipython-input-551-4e7fa5e27e5c>", line 2, in weighted_average
if (grp['x'] > 0).all() & (grp['y'] > 0).all():
File "/anaconda3/lib/python3.7/site-packages/pandas/core/series.py", line 871, in __getitem__
result = self.index.get_value(self, key)
File "/anaconda3/lib/python3.7/site-packages/pandas/core/indexes/base.py", line 4404, in get_value
return self._engine.get_value(s, k, tz=getattr(series.dtype, "tz", None))
File "pandas/_libs/index.pyx", line 80, in pandas._libs.index.IndexEngine.get_value
File "pandas/_libs/index.pyx", line 90, in pandas._libs.index.IndexEngine.get_value
File "pandas/_libs/index.pyx", line 135, in pandas._libs.index.IndexEngine.get_loc
File "pandas/_libs/index_class_helper.pxi", line 109, in pandas._libs.index.Int64Engine._check_type
KeyError: 'x'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<ipython-input-560-985ff89495dc>", line 1, in <module>
combined = anscombe.groupby(by='dataset').agg([weighted_average, reverse_sumsquares])
File "/anaconda3/lib/python3.7/site-packages/pandas/core/groupby/generic.py", line 928, in aggregate
result, how = self._aggregate(func, *args, **kwargs)
File "/anaconda3/lib/python3.7/site-packages/pandas/core/base.py", line 477, in _aggregate
return self._aggregate_multiple_funcs(arg, _axis=_axis), None
File "/anaconda3/lib/python3.7/site-packages/pandas/core/base.py", line 523, in _aggregate_multiple_funcs
new_res = colg.aggregate(arg)
File "/anaconda3/lib/python3.7/site-packages/pandas/core/groupby/generic.py", line 253, in aggregate
ret = self._aggregate_multiple_funcs(func)
File "/anaconda3/lib/python3.7/site-packages/pandas/core/groupby/generic.py", line 321, in _aggregate_multiple_funcs
results[name] = obj.aggregate(func)
File "/anaconda3/lib/python3.7/site-packages/pandas/core/groupby/generic.py", line 269, in aggregate
result = self._aggregate_named(func, *args, **kwargs)
File "/anaconda3/lib/python3.7/site-packages/pandas/core/groupby/generic.py", line 452, in _aggregate_named
output = func(group, *args, **kwargs)
File "<ipython-input-551-4e7fa5e27e5c>", line 2, in weighted_average
if (grp['x'] > 0).all() & (grp['y'] > 0).all():
File "/anaconda3/lib/python3.7/site-packages/pandas/core/series.py", line 871, in __getitem__
result = self.index.get_value(self, key)
File "/anaconda3/lib/python3.7/site-packages/pandas/core/indexes/base.py", line 4404, in get_value
return self._engine.get_value(s, k, tz=getattr(series.dtype, "tz", None))
File "pandas/_libs/index.pyx", line 80, in pandas._libs.index.IndexEngine.get_value
File "pandas/_libs/index.pyx", line 90, in pandas._libs.index.IndexEngine.get_value
File "pandas/_libs/index.pyx", line 135, in pandas._libs.index.IndexEngine.get_loc
File "pandas/_libs/index_class_helper.pxi", line 109, in pandas._libs.index.Int64Engine._check_type
KeyError: 'x'
Альтернативное сообщение об ошибке при переопределении функции средневзвешенного значения
Если функция weighted_average(grp)
переопределена как
def weighted_average(grp):
if (grp.x > 0).all() & (grp.y > 0).all():
return np.average(grp.x, weights=1/(grp.y)**2)
else:
return 0
сообщение об ошибке отличается:
File "<ipython-input-561-7d231f4ec5cf>", line 2, in weighted_average
if (grp.x > 0).all() & (grp.y > 0).all():
File "/anaconda3/lib/python3.7/site-packages/pandas/core/generic.py", line 5274, in __getattr__
return object.__getattribute__(self, name)
AttributeError: 'Series' object has no attribute 'x'
Возможно, это говорит о том, что при вызове через .agg
функция weighted_average(grp)
ожидает grp
как Series
, а не groupby
pandas объект ?
Стоит отметить, что метод .agg
работает правильно на том же groupby
объект при применении относительно более простых функций, таких как:
combined = anscombe.groupby(by='dataset').agg([np.sum, np.std])
примечание: это независимая попытка решения проблемы, которую я описал в другом вопросе .
Python: 3.7.2, pandas: 1.0.3