Замените группы, которые имеют размер> 1, средним значением в кадре данных панд - PullRequest
0 голосов
/ 03 декабря 2018

Итак, я хочу сгруппировать по определенным столбцам и для каждой группы, размер которой больше 1, взять среднее значение в остальных столбцах (если все значения равны nan, тогда это должно быть nan, если нет, я хочу, чтобы nans отбрасывалось в среднеерасчет, который является поведением по умолчанию).Тогда я хочу убрать лишние строки.Код ниже делает это:

import pandas as pd
import numpy as np

df = pd.DataFrame(
    [[1, np.nan, 100, 63], [2, np.nan, 101, 63], [2, 12, 102, 63],
     [2, 14, 102, 63], [2, 14, 102, 64], [1, np.nan, 200, 63]],
    columns=['group', 'value', 'value2', 'dummy'])
print(df)
df = df.set_index(['group', 'dummy'])
groupby = df.groupby(['group', 'dummy'])
idx = groupby.size() > 1
df_groups_to_process = df.loc[idx]
# the code below would calculate the mean for all groups, huge performance hit
# df.loc[idx, ['value', 'value2']] = \
#     groupby[['value', 'value2']].transform('mean')[idx].values
df.loc[idx, ['value', 'value2']] = \
    df_groups_to_process.groupby(['group', 'dummy'])[
        ['value', 'value2']].transform('mean').values
print(df)
df = df.groupby(['group', 'dummy']).first()
print(df)

отпечатки:

   group  value  value2  dummy
0      1    NaN     100     63
1      2    NaN     101     63
2      2   12.0     102     63
3      2   14.0     102     63
4      2   14.0     102     64
5      1    NaN     200     63
sys:1: PerformanceWarning: indexing past lexsort depth may impact performance.
             value      value2
group dummy                   
1     63       NaN  150.000000
2     63      13.0  101.666667
      63      13.0  101.666667
      63      13.0  101.666667
      64      14.0  102.000000
1     63       NaN  150.000000
             value      value2
group dummy                   
1     63       NaN  150.000000
2     63      13.0  101.666667
      64      14.0  102.000000

Process finished with exit code 0

Однако есть несколько вещей, которые можно улучшить:

  • df_groups_to_process = df.loc[idx]не уверен, что это создаст копию, но поскольку мои реальные данные огромны, я бы хотел вообще избежать этого и включить их в df.loc[idx, ['value', 'value2']] = ... строку
  • Я повторяю операцию groupby в конце, чтобы сначала вызвать - какможно ли этого избежать?
  • бонус: sys:1: PerformanceWarning: indexing past lexsort depth may impact performance. - не уверен, о чем идет речь (на самом деле я не вижу его на сервере).Как я могу это исправить?

1 Ответ

0 голосов
/ 03 декабря 2018

Среднее значение одного значения - это само значение, поэтому, если я что-то упускаю, нет необходимости проводить различие по размеру группы.

Рассмотрим

>>> df
   group  value  value2  dummy
0      1    NaN     100     63
1      2    NaN     101     63
2      2   12.0     102     63
3      2   14.0     102     63
4      2   14.0     102     64
5      1    NaN     200     63
>>> 
>>> df.groupby(['group', 'dummy']).mean()
             value      value2
group dummy                   
1     63       NaN  150.000000
2     63      13.0  101.666667
      64      14.0  102.000000

Это выглядит такваш ожидаемый результат.Пожалуйста, оставьте комментарий, если это решит проблему для всех входных фреймов данных, которые вы, возможно, рассматриваете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...