Агрегирование и / или группировка Dataframe Pandas

У меня есть такой фрейм данных:

serie  = [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]
values = [2, 2, 2, 1, 2, 2, 1, 1, 1, 1, 1, 2]

series_X_values = {'series': serie, 'values': values}

df_mytest = pd.DataFrame.from_dict(series_X_values)
df_mytest

Мне нужно создать третий столбец (например, чаще)

df_mytest['most_frequent'] = np.nan

чьи значения будут наиболее часто встречаться в столбце "значения", сгруппированном по "сериям", или замените значения в столбце "значения" самим наиболее часто встречающимся термином, как в кадре данных ниже:

serie  = [1, 2, 3]
values = [2, 2, 1]

series_X_values = {'series': serie, 'values': values}

df_mytest = pd.DataFrame.from_dict(series_X_values)
df_mytest

Я пробовал несколько неудачных вариантов, например:

def personal_most_frequent(col_name):
  from sklearn.impute import SimpleImputer
  imp = SimpleImputer(strategy="most_frequent")

  return imp

df_result = df_mytest.groupby('series').apply(personal_most_frequent('values'))

но...

TypeError Traceback (последний вызов последний) /usr/local/lib/python3.6/dist-packages/pandas/core/groupby/groupby.py в apply (self, func, * args, ** kwargs) 688 попробуйте: - -> 689 result = self._python_apply_general (f) 690 кроме исключения:

5 кадров /usr/local/lib/python3.6/dist-packages/pandas/core/groupby/groupby.py в _python_apply_general (self, f) 706 ключей, значений, mutated = self.grouper.apply (f, self. _selected_obj, -> 707 self.axis) 708

/usr/local/lib/python3.6/dist-packages/pandas/core/groupby/ops.py в apply (self, f, data, axis) 189 group_axes = _get_axes (group) -> 190 res = f ( group) 191, если не _is_indexed_like (res, group_axes):

TypeError: объект SimpleImputer не вызывается

Во время обработки вышеуказанного исключения произошло другое исключение:

TypeError Traceback (последний вызов последним) in () 5 return imp 6 ----> 7 df_result = df_mytest.groupby ('series'). Apply (personal_most_frequent ('values'))

/usr/local/lib/python3.6/dist-packages/pandas/core/groupby/groupby.py в apply (self, func, * args, ** kwargs) 699 700 с _group_selection_context (self): -> 701 return self._python_apply_general (f) 702 703 вернуть результат

/usr/local/lib/python3.6/dist-packages/pandas/core/groupby/groupby.py в _python_apply_general (self, f) 705 def _python_apply_general (self, f): 706 ключей, значений, mutated = self.grouper .apply (f, self._selected_obj, -> 707 self.axis) 708 709 return self._wrap_applied_output (

/usr/local/lib/python3.6/dist-packages/pandas/core/groupby/ops.py в apply (self, f, data, axis) 188 # группа может быть изменена 189 group_axes = _get_axes (group) - > 190 res = f (group) 191, если не _is_indexed_like (res, group_axes): 192 mutated = True

TypeError: объект SimpleImputer не вызывается

а также...

df_mytest.groupby(['series', 'values']).agg(lambda x:x.value_counts().index[0])

но опять же ...

IndexError Traceback (последний вызов последний) /usr/local/lib/python3.6/dist-packages/pandas/core/groupby/ops.py в agg_series (self, obj, func) 589 try: -> 590 return self ._aggregate_series_fast (obj, func) 591 кроме исключения:

12 кадров pandas / _libs / reduce.pyx в pandas._libs.reduction.SeriesGrouper.get_result ()

pandas / _libs / reduce.pyx в pandas._libs.reduction.SeriesGrouper.get_result ()

IndexError: индекс 0 выходит за пределы оси 0 с размером 0

Во время обработки вышеуказанного исключения произошло другое исключение:

IndexError Traceback (последний вызов последним) /usr/local/lib/python3.6/dist-packages/pandas/core/indexes/base.py в getitem (self, key) 3956, если is_scalar ( key): 3957 key = com.cast_scalar_indexer (key) -> 3958 return getitem (key) 3959 3960 if isinstance (key, slice):

IndexError: индекс 0 выходит за пределы оси 0 с размером 0

Я прошу помощи у сообщества, чтобы завершить этот процесс.


person Ângelo    schedule 27.09.2019    source источник
comment
Как это должно вести себя в случае серии 2, где значения 1 и 2 имеют одинаковые значения?   -  person Leo    schedule 28.09.2019


Ответы (1)


Предполагая, что у вас все в порядке с одинаково представленными значениями с разрывом связей, взяв максимальное значение, вы можете сделать что-то вроде:

df_mf = df_mytest.groupby('series')['values'].apply(lambda ds: ds.mode().max()).to_frame('most_frequent')

df_mytest.merge(df_mf, 'left', left_on='series', right_index=True)

Из:

    series  values  most_frequent
0        1       2              2
1        1       2              2
2        1       2              2
3        1       1              2
4        2       2              2
5        2       2              2
6        2       1              2
7        2       1              2
8        3       1              1
9        3       1              1
10       3       1              1
11       3       2              1
person Leo    schedule 27.09.2019