Панды группируются по нескольким столбцам, фильтруют и принимают соотношение средних - PullRequest
2 голосов
/ 02 мая 2019

Я хотел бы сгруппировать фрейм данных, используя два столбца, затем отфильтровать результаты, которые имеют значение, меньшее некоторого порогового значения, и затем принять соотношение средних значений.

Пример:

grouped_df = df_test[["bool_column", "A", "B",
        "C", "filter_column"]].groupby(["filter_column", "bool_column"])
grouped_df.describe()

Это дает мне что-то вроде:

                   bool_column       A       B       C
filter_column

Name1                 True       <stats> <stats> <stats> [count = 4]
                      False      <stats> <stats> <stats> [count = 2]
Name2                 True       <stats> <stats> <stats> [count = 3]
                      False      <stats> <stats> <stats> [count = 1]

Теперь я хочу отфильтровать те поля, где количество <2. Итак, я хочу: </p>

                   bool_column       A       B       C
filter_column

Name1                 True       <stats> <stats> <stats> [count = 4]
                      False      <stats> <stats> <stats> [count = 2]
Name2                 True       <stats> <stats> <stats> [count = 3]

После этого я хочу взять соотношение средних значений столбцов A, B и C.То есть для каждого столбца фильтра мне нужно

colA[True].mean / colb[False].mean

Я все равно не мог заставить фильтр работать.Я попробовал следующее:

  1. grouped_df2 = grouped_df.filter(lambda x: len(x) > 1)
  2. grouped_df2 = grouped_df2.stack()
  3. grouped_df = grouped_df.filter(lambda x: len(x) > 0)

Следующие работы, чтобы получитьсоотношение:

df = grouped_df['A'].mean().unstack('bool_column')
df = df[(df[True] > 0) & (df[False] > 0)]
df['ratio'] = df[True] / df[False]
df = df.drop(columns=[True,False])
df.plot(kind='bar')

1 Ответ

1 голос
/ 03 мая 2019

Это одно из возможных решений, сначала объедините среднее значение и число для каждой группы:

df = grouped_df.agg([np.mean, 'count'])

Затем отфильтруйте строки, в которых число слишком мало:

df = df[df['A', 'count'] > 1]

Удалите ненужные столбцы и переименуйте:

df = df.drop('count', axis=1, level=1)
df.columns = df.columns.get_level_values(0)

Чтобы вычислить среднее значение, сначала снимите со стека bool_column, а затем добавьте новый столбец ratio для каждого столбца данных:

df = df.unstack()

for col in df.columns.get_level_values(0).unique():
    df[col, 'ratio'] = df[col, True] / df[col, False]

Наконец, выберите только столбцы ratio:

df.iloc[:, df.columns.get_level_values(1) == 'ratio']

Результат:

                  A      B
  bool_column     ratio  ratio
filter_column       
            1       NaN    NaN
            2  0.857143  0.875
...