Как частично транспонировать панды в датафрейм - PullRequest
2 голосов
/ 22 октября 2019

У меня есть вопрос, похожий на этот здесь . Я хотел бы частично перенести pandas dataframe. Я получил в руки фрейм данных, похожий на следующий:

data = [{"Student" : "john", "Subject" : 'Math', 'Plan_Actual_Delta' : 'Plan' , "2009" : 100, "2010" : 100},
            {"Student" : "john", "Subject" : 'Math', 'Plan_Actual_Delta' : 'Actual' ,"2009" : 80, "2010" : 100}, 
            {"Student" : "john", "Subject" : 'Math' , 'Plan_Actual_Delta' : 'Delta' ,"2009" : -20, "2010" : 0},
            {"Student" : "lisa", "Subject" : 'Math', 'Plan_Actual_Delta' : 'Plan' ,"2009" : 80, "2010" : 100},
            {"Student" : "lisa", "Subject" : 'Math', 'Plan_Actual_Delta' : 'Actual' ,"2009" : 75, "2010" : 100},
            {"Student" : "lisa", "Subject" : 'Math', 'Plan_Actual_Delta' : 'Delta' ,"2009" : -5, "2010" : 0}]

df = pd.DataFrame(data)

Он показывает студентов и их запланированные и фактические результаты (и дельту) по заданному предмету в течение данного года. Годы являются столбцами в этом примере. И в строках указывается, показывает ли строка запланированный, фактический или дельта успеваемости учащихся.

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

data = [{"Student" : "john", "Subject" : 'Math', 'Year': '2009', 'Plan':100, 'Actual':80, 'Delta': -20},
       {"Student" : "john", "Subject" : 'Math', 'Year': '2010', 'Plan':100, 'Actual':100, 'Delta': 0},
        {"Student" : "lisa", "Subject" : 'Math', 'Year': '2009', 'Plan':80, 'Actual':75, 'Delta': -5},
       {"Student" : "lisa", "Subject" : 'Math', 'Year': '2010', 'Plan':100, 'Actual':100, 'Delta': 0}]

df = pd.DataFrame(data)

Как бы вы это сделали? Заранее спасибо / R

1 Ответ

3 голосов
/ 22 октября 2019

Используйте DataFrame.set_index с изменением формы на DataFrame.stack и Series.unstack на третий уровень:

df = (df.set_index(['Student','Subject','Plan_Actual_Delta'])
        .rename_axis('Year', axis=1)
        .stack()
        .unstack(2)
        .reset_index()
        .rename_axis(None, axis=1))
print (df)
  Student Subject  Year  Actual  Delta  Plan
0    john    Math  2009      80    -20   100
1    john    Math  2010     100      0   100
2    lisa    Math  2009      75     -5    80
3    lisa    Math  2010     100      0   100

Другое решение, если сначала не работает с возможным агрегированием с DataFrame.melt и DataFrame.pivot_table:

df = (df.melt(['Student','Subject','Plan_Actual_Delta'], var_name='Year')
        .pivot_table(index=['Student','Subject','Year'], 
                     columns='Plan_Actual_Delta',
                     values='value',
                     aggfunc='mean')
        .reset_index()
        .rename_axis(None, axis=1)
)
print (df)
  Student Subject  Year  Actual  Delta  Plan
0    john    Math  2009      80    -20   100
1    john    Math  2010     100      0   100
2    lisa    Math  2009      75     -5    80
3    lisa    Math  2010     100      0   100
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...