Я пытаюсь сгенерировать функцию пользовательского режима для groupby для столбца b
, которая выберет режим столбца a
в каждой группе. Мой процесс выбора выглядит следующим образом:
- Если режим уникален, просто выберите этот режим
- Если режим не уникален, выберите значение в столбце
a
, которое разделяет индекс со значением в столбце c == 1
Функция и тест DataFrame приведены ниже.
def custom_mode(x):
first = x['c'].loc[x['c'] == 1].index
counts = x['a'].value_counts()
ans = x['a'].loc[first]
if len(counts.index) == 1:
return counts.index[0]
elif counts.iloc[0] == counts.iloc[1]:
return ans
else:
return counts.index[0]
df = pd.DataFrame({'a':[1,2,2,1,3,4,4,4],'b':[2,2,2,2,5,5,5,5], 'c':[1,2,3,4,5,1,2,3]})
df
Out[223]:
a b c
0 1 2 1
1 2 2 2
2 2 2 3
3 1 2 4
4 3 5 5
5 4 5 1
6 4 5 2
7 4 5 3
Однако, когда я запускаю функцию применения groupby, я получаю следующую ошибку:
df.groupby('b').apply(custom_mode)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
//anaconda3/lib/python3.7/site-packages/pandas/core/groupby/groupby.py in apply(self, func, *args, **kwargs)
724 try:
--> 725 result = self._python_apply_general(f)
726 except Exception:
//anaconda3/lib/python3.7/site-packages/pandas/core/groupby/groupby.py in _python_apply_general(self, f)
744 return self._wrap_applied_output(
--> 745 keys, values, not_indexed_same=mutated or self.mutated
746 )
//anaconda3/lib/python3.7/site-packages/pandas/core/groupby/generic.py in _wrap_applied_output(self, keys, values, not_indexed_same)
410 applied_index = self._selected_obj._get_axis(self.axis)
--> 411 all_indexed_same = _all_indexes_same([x.index for x in values])
412 singular_series = len(values) == 1 and applied_index.nlevels == 1
//anaconda3/lib/python3.7/site-packages/pandas/core/groupby/generic.py in <listcomp>(.0)
410 applied_index = self._selected_obj._get_axis(self.axis)
--> 411 all_indexed_same = _all_indexes_same([x.index for x in values])
412 singular_series = len(values) == 1 and applied_index.nlevels == 1
AttributeError: 'numpy.int64' object has no attribute 'index'
During handling of the above exception, another exception occurred:
AttributeError Traceback (most recent call last)
<ipython-input-224-dea20230c0ea> in <module>
----> 1 df.groupby('b').apply(custom_mode)
//anaconda3/lib/python3.7/site-packages/pandas/core/groupby/groupby.py in apply(self, func, *args, **kwargs)
735
736 with _group_selection_context(self):
--> 737 return self._python_apply_general(f)
738
739 return result
//anaconda3/lib/python3.7/site-packages/pandas/core/groupby/groupby.py in _python_apply_general(self, f)
743
744 return self._wrap_applied_output(
--> 745 keys, values, not_indexed_same=mutated or self.mutated
746 )
747
//anaconda3/lib/python3.7/site-packages/pandas/core/groupby/generic.py in _wrap_applied_output(self, keys, values, not_indexed_same)
409 if isinstance(v, Series):
410 applied_index = self._selected_obj._get_axis(self.axis)
--> 411 all_indexed_same = _all_indexes_same([x.index for x in values])
412 singular_series = len(values) == 1 and applied_index.nlevels == 1
413
//anaconda3/lib/python3.7/site-packages/pandas/core/groupby/generic.py in <listcomp>(.0)
409 if isinstance(v, Series):
410 applied_index = self._selected_obj._get_axis(self.axis)
--> 411 all_indexed_same = _all_indexes_same([x.index for x in values])
412 singular_series = len(values) == 1 and applied_index.nlevels == 1
413
AttributeError: 'numpy.int64' object has no attribute 'index'
Что здесь происходит? Я могу получить доступ к обоим столбцам, так как могу вернуть переменную ans отдельно, но не при выборе этого параметра в операторах if. См. Ниже:
def custom_mode(x):
first = x['c'].loc[x['c'] == 1].index
counts = x['a'].value_counts()
ans = x['a'].loc[first]
return ans
df.groupby('b').apply(custom_mode)
Out[226]:
b
2 0 1
5 5 4
Name: a, dtype: int64
Это работает до тех пор, пока я почему-то не пытаюсь вернуть "ans":
def custom_mode(x):
first = x['c'].loc[x['c'] == 1].index
counts = x['a'].value_counts()
ans = x['a'].loc[first]
if len(counts.index) == 1:
return counts.index[0]
elif counts.iloc[0] == counts.iloc[1]:
return 'p'
else:
return counts.index[0]
df.groupby('b').apply(custom_mode)
Out[228]:
b
2 p
5 4
dtype: object
Я предпочитаю понять, почему это не так работать, но в качестве альтернативы, если у вас есть предложение о том, как реализовать этот лог c, пожалуйста, отправьте это.