У меня есть следующий фрейм данных:
dic = {'US':{'Quality':{'points':"-2 n", 'difference':'equal', 'stat': 'same'}, 'Prices':{'points':"-7 n", 'difference':'negative', 'stat': 'below'}, 'Satisfaction':{'points':"3 n", 'difference':'positive', 'stat': 'below'}},
'UK': {'Quality':{'points':"3 n", 'difference':'equal', 'stat': 'above'}, 'Prices':{'points':"-13 n", 'difference':'negative', 'stat': 'below'}, 'Satisfaction':{'points':"2 n", 'difference':'negative', 'stat': 'same'}}}
d1 = defaultdict(dict)
for k, v in dic.items():
for k1, v1 in v.items():
for k2, v2 in v1.items():
d1[(k, k2)].update({k1: v2})
df = pd.DataFrame(d1)
df.columns = df.columns.rename("Skateboard", level=0)
df.columns = df.columns.rename("Q3", level=1)
df.insert(loc=0, column=('', 'Mode'), value = "Website")
На данный момент это выглядит так:
Как добавить еще один уровень заголовков в мультииндексный фрейм данных, чтобы он выглядел как на картинке ниже?
Обновлять:
dic = {'US':{'Quality':{'points':"-2 n", 'difference':'equal', 'stat': 'same'}, 'Prices':{'points':"-7 n", 'difference':'negative', 'stat': 'below'}, 'Satisfaction':{'points':"3 n", 'difference':'positive', 'stat': 'below'}},
'UK': {'Quality':{'points':"3 n", 'difference':'equal', 'stat': 'above'}, 'Prices':{'points':"-13 n", 'difference':'negative', 'stat': 'below'}, 'Satisfaction':{'points':"2 n", 'difference':'negative', 'stat': 'same'}}}
d1 = defaultdict(dict)
for k, v in dic.items():
for k1, v1 in v.items():
for k2, v2 in v1.items():
d1[(k, k2)].update({k1: v2})
df = pd.DataFrame(d1)
df.columns = df.columns.rename("Skateboard", level=0)
df.columns = df.columns.rename("Metric", level=1)
df1 = df.xs('points', axis=1, level=1, drop_level=False)
df2 = df.drop('points', axis=1, level=1)
df3 = (pd.concat([df1, df2], keys=['GM', ''], axis=1)
.swaplevel(0, 1, axis=1)
.sort_index(axis=1))
df3.columns = df3.columns.rename("Q3", level=1)
df3.insert(loc=0, column=('','', 'Mode'), value = "Website")
df3
Теперь фрейм данных выглядит так:
Как переместить заголовок GM на первое место в столбце как для США, так и для Великобритании (конечный результат см. на втором изображении)?
Пример
data = {('A', 'a'): {0: 8, 1: 3, 2: 4},
('A', 'b'): {0: 5, 1: 7, 2: 8},
('A', 'c'): {0: 1, 1: 7, 2: 6},
('B', 'a'): {0: 7, 1: 1, 2: 0},
('B', 'b'): {0: 1, 1: 1, 2: 7},
('B', 'c'): {0: 7, 1: 7, 2: 4}}
df = pd.DataFrame(data)
df
A B
a b c a b c
0 8 5 1 7 1 7
1 3 7 7 1 1 7
2 4 8 6 0 7 4
Код
создайте новый уровень и добавьте c
в столбец a
, добавьте d
кроме a
дф с a
(df1
)
df1 = df.xs('a', axis=1, level=1, drop_level=False)
вывод (df1
):
A B
a a
0 8 7
1 3 1
2 4 0
df кроме a
(df2
)
df2 = df.drop('a', axis=1, level=1)
вывод (df2
):
A B
b c b c
0 5 1 1 7
1 7 7 1 7
2 8 6 7 4
объединить df1 и df2 с key
pd.concat([df1, df2], keys=['c', 'd'], axis=1)
выход:
c d
A B A B
a a b c b c
0 8 7 5 1 1 7
1 3 1 7 7 1 7
2 4 0 8 6 7 4
уровень подкачки и сортировка
(pd.concat([df1, df2], keys=['c', 'd'], axis=1)
.swaplevel(0, 1, axis=1)
.sort_index(axis=1))
результат:
A B
c d c d
a b c a b c
0 8 5 1 7 1 7
1 3 7 7 1 1 7
2 4 8 6 0 7 4
мы можем добавить уровень к столбцам
или используйте простой способ
df3 = pd.concat([df], keys=[''], names=['Q3'], axis=1).swaplevel(0, 1, axis=1)
df3.columns = df3.columns.map(lambda x: (x[0], 'c', x[2]) if x[2] == 'a' else x)
df3
A B
Q3 c c
a b c a b c
0 8 5 1 7 1 7
1 3 7 7 1 1 7
2 4 8 6 0 7 4
Простое решение состоит в том, чтобы сделать ключ в алфавитном порядке. и вы можете переименовать ключ в GM
Хорошо, я пытался это df3.sortlevel(level = 1, ascending = False)
. Но выдает ошибку: объект DataFrame не имеет атрибута sortlevel.
я обновляю свой ответ более простым кодом
Когда я экспортирую df3 в excel, он объединяет столбец уровня 1 c, охватывающий столбцы уровня 2: a, b, c. Я только хочу, чтобы он был выше столбца уровня 2 a
Обновленный код в моем посте после экспорта не объединяет столбец c. Его нужно только отсортировать.
Я использовал ваш код в качестве шаблона для работы с моим фреймворком данных. Некоторые изменения все еще необходимы, чтобы получить требуемый результат. Я сделал обновление в своем посте. Пожалуйста, проверьте.