Как преобразовать DataFrame с 1-уровневой иерархией индекса на 3 уровня - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть плоский DataFrame, подобный этому:

enter image description here

И я хотел бы преобразовать это в DataFrame следующим образом:

enter image description here

Для каждого теста (T) для каждой версии (версии) я хотел бы суммировать количество ответов, сопоставленных по данной шкале Ликерта (я сократил его до3 записи для демонстрационных целей) в процентах.

Весь набор значений шкалы Ликерта для каждой комбинации T и Version должен составлять до 100%.

likert = {
    'Agree': 1,
    'Undecided': 2,
    'Disagree': 3,
}

Как это возможно?Спасибо за вашу помощь!

1 Ответ

0 голосов
/ 08 февраля 2019

Возможно, это не самое элегантное решение, но я думаю, что оно достигает вашей цели.Предположим, ваш фрейм данных называется df (я случайно выбрал шкалу, поэтому мой df не совсем то, что вы описали):

res = df.melt(id_vars=['T', 'Version'], value_vars=['Q1', 'Q2'], value_name='Scale')

Это преобразует ваш фрейм данных в длинный формат:

#     T Version variable      Scale
# 0   1       A       Q1  Undecided
# 1   1       A       Q1   Disagree
# 2   1       A       Q1  Undecided
# 3   1       A       Q1      Agree

Затем вы хотите вычислить размер каждой комбинации ваших переменных, что может быть выполнено следующим образом:

res = res.groupby(['T', 'Version', 'Scale', 'variable']).size()

Что дает:

# T  Version  Scale      variable
# 1  A        Agree      Q1          2
#                        Q2          1
#             Disagree   Q2          3
#             Undecided  Q1          2
#    B        Agree      Q1          1

Тогда,чтобы переместить Q1 и Q2 в столбцы, вы разбираете последний уровень индекса следующим образом:

res = res.unstack(level=-1).fillna(0)

# variable              Q1   Q2
# T Version Scale
# 1 A       Agree      2.0  1.0
#           Disagree   0.0  3.0
#           Undecided  2.0  0.0

Наконец, чтобы вычислить процент для каждой комбинации первых двух уровней индекса:

res = res.groupby(level=[0, 1]).apply(lambda x: 100. * x / x.sum())

Что дает желаемый результат:

# variable                     Q1         Q2
# T Version Scale
# 1 A       Agree       50.000000  25.000000
#           Disagree     0.000000  75.000000
#           Undecided   50.000000   0.000000
#   B       Agree       33.333333   0.000000
#           Disagree    66.666667  66.666667
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...