IIUC, вы хотите использовать одну группу для выполнения вычислений для столбцов Month1
Month2
и Month3
? Например, mean - std
и mean + std
у вас внизу кода?
Вот способ, которым вы можете сделать это:
np.random.seed(87) # Use this for reproducibility
df9 = pd.DataFrame(np.random.randint(0,3,(10,5)),\
columns = ['Month1','Month2','Month3','Revised Category','useless column'])
agg = df9[['Month1','Month2','Month3','Revised Category']].\
groupby('Revised Category').agg(lambda x: [x.mean()-x.std(),x.mean()+x.std()])
agg = pd.concat([pd.DataFrame.from_items(zip(agg.index, agg[col].values)).T for col in agg],axis=1)
agg.columns = ['Month1_low','Month1_up','Month2_low','Month2_up','Month3_low','Month3_up']
И вывод:
Month1_low Month1_up Month2_low Month2_up Month3_low Month3_up
0 -0.414214 2.414214 -0.414214 2.414214 -0.207107 1.207107
1 -0.207107 1.207107 -0.207107 1.207107 -0.207107 1.207107
2 0.183475 2.149859 0.105573 1.894427 0.663340 2.336660
Индекс в этом новом agg
фрейме данных представляет ваши категории. Поэтому, если вы хотите получить доступ, скажем Month1_up
для категории 0
, просто нарежьте: agg.loc[0,'Month1_up']
.
Если вы хотите рассчитать среднее значение за все ваши месяцы за один раз, вы можете объединить исходный кадр данных перед групповой, например:
concatenated = pd.concat([df9[[col,'Revised Category']].rename({col:'Month'},axis = 1) \
for col in ['Month1','Month2','Month3']])
concatenated.groupby('Revised Category').agg(lambda x: [x.mean()-x.std(),x.mean()+x.std()])
agg2 = pd.DataFrame.from_items(zip(agg2.index, agg2.Month.values)).T
agg2.columns = ['Months_low','Months_up']
Months_low Months_up
0 -0.149859 1.816525
1 -0.047723 1.047723
2 0.344018 2.100426
EDIT:
Я не использую для раскрашивания фреймов данных, так что это решение может быть тяжелым и недопустимым, но оно работает на примере.
Сначала давайте перегруппируем исходные данные из df9
и данные, которые мы вычислили с помощью groupby
(с верхними и нижними границами):
months = ['Month1','Month2','Month3']
conc2 = pd.concat([df9.set_index('Revised Category')[[col]].join(\
agg[[col+'_low',col+'_up']]) for col in months],axis = 1)
Month1 Month1_low Month1_up Month2 Month2_low Month2_up Month3 Month3_low Month3_up
0 2 -0.414214 2.414214 0 -0.414214 2.414214 0 -0.207107 1.207107
0 0 -0.414214 2.414214 2 -0.414214 2.414214 1 -0.207107 1.207107
1 1 -0.207107 1.207107 0 -0.207107 1.207107 0 -0.207107 1.207107
Мы будем использовать это для создания маски для кода, где значение в одном из столбцов Month
выше соответствующей верхней границы.
Эта маска будет затем использоваться для применения требуемых цветов к стилю кадра данных.
mask = conc2.apply(lambda x: pd.Series([x[col]<x[col+'_low'] for col in months]),axis = 1)
mask.columns = months # the columns names need to be the same as conc2 for apply below
Month1 Month2 Month3
0 False False False
0 False False False
1 False False False
Теперь, когда мы создали нашу логическую маску, нам нужно заменить ее значения соответствующими цветными сообщениями, воспринимаемыми объектом style
в пандах.
mask = mask.reset_index(drop = True).apply(lambda x: x.map(\
{True:'background-color: red',False:'background-color: None'}))
И теперь, когда у нас есть эти строки в нашей маске, мы просто должны применить их к стилю нашего информационного кадра, чтобы напечатать его в цвете.
conc2[months].reset_index(drop = True).style.apply(lambda x: mask, axis=None)