Pandas GroupBy Применение странного поведения: ошибка индекса при вызове двух разных столбцов в кадре данных для расчета режима - PullRequest
0 голосов
/ 28 января 2020

Я пытаюсь сгенерировать функцию пользовательского режима для 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, пожалуйста, отправьте это.

...