Как использовать значения сумм из столбца в многоуровневом индексированном фрейме данных pandas в качестве условия для значений в новом столбце - PullRequest
1 голос
/ 30 марта 2019

У меня есть многоуровневый индексный панд данных.Я хотел бы создать новый столбец, где значения в этом столбце основаны на условии.Это условие основано на суммировании другого столбца для этого индекса, который затем делится пополам.Если это меньше, чем последнее значение, которое хранится в отдельном списке, то значение в новом столбце принимает те же значения, что и другой столбец в кадре данных.Если это условие не выполняется, тогда все значения в новом столбце должны быть 0.

Используя этот вопрос, чтобы попытаться достичь этого Суммируйте столбцы по уровням в многоиндексном фрейме данных IЯ использовал комбинацию np.where и df.sum(level=0, axis=1), но это приводит к следующей ошибке:

ValueError: operands could not be broadcast together with shapes (2,8) (21,) ()

Вот пример моего фрейма данных и кода, который я использовал до сих пор:

import pandas as pd
import numpy as np

balance = [1400]

data = {'EVENT_ID': [112335580,112335580,112335580,112335580,112335580,112335580,112335580,112335580, 112335582,
                     112335582,112335582,112335582,112335582,112335582,112335582,112335582,112335582,112335582,
                     112335582,112335582,112335582],

 'SELECTION_ID': [6356576,2554439,2503211,6297034,4233251,2522967,5284417,7660920,8112876,7546023,8175276,8145908,
                  8175274,7300754,8065540,8175275,8106158,8086265,2291406,8065533,8125015],

 'Pot_Bet': [3.236731,2.416966,2.278365,2.264023,2.225353,2.174407, 2.141420,2.122386,2.832997,2.411094,
         2.167218,2.138972,2.132137,2.128341,2.116338,2.115239,2.115123,2.114284362,2.113420,
         2.113186,2.112729],

  'Liability':[3.236731, 2.416966, 12.245492, 12.795112, 15.079176, 23.336171, 50.741182, 571.003118, 2.832997, 6.691736, 15.808607, 27.935834, 35.954927, 43.275250, 147.165537, 193.017915, 199.622454, 265.809019, 405.808678, 473.926781, 706.332594]}

df = pd.DataFrame(data, columns=['EVENT_ID', 'SELECTION_ID', 'Pot_Bet','WIN_LOSE'])

df.set_index(['EVENT_ID', 'SELECTION_ID'], inplace=True) #Selecting columns for indexing

df['Bet'] = np.where(df.sum(level = 0) > 0.5*balance[-1], df['Pot_Bet'], 0)

Это приводит к ошибке, указанной ранее.

Для индекса 112335580 новый столбец должен иметь те же значения, что и 'Pot_Bet'.В то время как для индекса 112335582 новый столбец должен иметь значения 0.

Cheers, Sandy

1 Ответ

1 голос
/ 30 марта 2019

Проблема в том, что если использовать df.sum(level=0), то же самое, что и df.groupby(level = 0).sum() - агрегирование по первому уровню MultiIndex.

Решение - использовать GroupBy.transform для Series стот же размер, что и у оригинала DataFrame:

df['Bet'] = np.where(df.groupby(level = 0)['Pot_Bet'].transform('sum') > 0.5*balance[-1], 
                     df['Pot_Bet'], 0)

Деталь :

print (df.groupby(level = 0)['Pot_Bet'].transform('sum'))
EVENT_ID   SELECTION_ID
112335580  6356576         18.859651
           2554439         18.859651
           2503211         18.859651
           6297034         18.859651
           4233251         18.859651
           2522967         18.859651
           5284417         18.859651
           7660920         18.859651
112335582  8112876         28.611078
           7546023         28.611078
           8175276         28.611078
           8145908         28.611078
           8175274         28.611078
           7300754         28.611078
           8065540         28.611078
           8175275         28.611078
           8106158         28.611078
           8086265         28.611078
           2291406         28.611078
           8065533         28.611078
           8125015         28.611078
Name: Pot_Bet, dtype: float64

Если необходима работа только с колонкой отточить, выберите ее для Series с помощьюимя столбца:

print (df['Pot_Bet'].sum(level=0))
EVENT_ID
112335580    18.859651
112335582    28.611078
Name: Pot_Bet, dtype: float64

print (df.groupby(level = 0)['Pot_Bet'].sum())
EVENT_ID
112335580    18.859651
112335582    28.611078
Name: Pot_Bet, dtype: float64
...