#python #pandas #dataframe
Вопрос:
У меня есть следующая многоиндексная таблица:
A | B | C | D | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
t_1 | t_2 | t_1 | t_2 | t_1 | t_2 | t_1 | t_2 | ||||||||
x | y | x | y | x | y | x | y | x | y | x | y | x | y | x | y |
2.2 | 5.1 | 3.4 | 1.8 | 1.5 | 6.7 | 8.1 | 7.5 | 6.1 | 2.1 | 9.3 | 7.1 | 8.2 | 1.1 | 1.4 | 2.5 |
7.9 | 3.2 | 1.1 | 5.3 | 9.3 | 3.1 | 0.9 | 3.2 | 4.1 | 5.1 | 7.7 | 4.3 | 8.1 | 0.4 | 2.4 | 4.1 |
Точки данных (x, y)
были случайным образом распределены по столбцам A — D. Я хочу переупорядочить их по x
значению t_1
, выделенному курсивом. Другие значения не имеют значения для повторного упорядочения, но переносятся в их новый столбец x
значением-at t_1
. Это означает, что каждая строка будет переупорядочена по-разному.
Мне нужен некоторый код, который обрабатывает приведенную выше таблицу для создания:
A | B | C | D | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
t_1 | t_2 | t_1 | t_2 | t_1 | t_2 | t_1 | t_2 | ||||||||
x | y | x | y | x | y | x | y | x | y | x | y | x | y | x | y |
1.5 | 6.7 | 8.1 | 7.5 | 2.2 | 5.1 | 3.4 | 1.8 | 6.1 | 2.1 | 9.3 | 7.1 | 8.2 | 1.1 | 1.4 | 2.5 |
4.1 | 5.1 | 7.7 | 4.3 | 7.9 | 3.2 | 1.1 | 5.3 | 8.1 | 0.4 | 2.4 | 4.1 | 9.3 | 3.1 | 0.9 | 3.2 |
Комментарии:
1. Я не понял вопроса. Пожалуйста, дайте более подробные объяснения. как вы получили эту таблицу результатов.
2. Кажется, что все x (t_1) находятся в порядке asc. и y (t_1) находятся в порядке убывания.
3. @Pygirl Я добавил еще несколько объяснений. Для сортировки используется только x(t_1), при этом значения y(t_1), x(t_2) и y(t_2) не являются релевантными, просто «переносятся» сортировкой x(t_1).
Ответ №1:
Вот вариант, включающий в основном вмешательство в форму данных, сортировку, а затем использование измененных значений и исходных df
столбцов (мультииндекс) для создания конечного кадра данных:
df2 = df.T.unstack(level=0).T.reset_index(level=0, col_fill='row')
df2 = df2.sort_values([('level_0', 'row'), ('t_1', 'x')], ignore_index=True)
values = df2.drop(('level_0', 'row'), axis=1).values.reshape(2, -1)
df3 = pd.DataFrame(data=values, columns=df.columns) # using original df's columns
Выход:
A B C D
t_1 t_2 t_1 t_2 t_1 t_2 t_1 t_2
x y x y x y x y x y x y x y x y
0 1.5 6.7 8.1 7.5 2.2 5.1 3.4 1.8 6.1 2.1 9.3 7.1 8.2 1.1 1.4 2.5
1 4.1 5.1 7.7 4.3 7.9 3.2 1.1 5.3 8.1 0.4 2.4 4.1 9.3 3.1 0.9 3.2
В более удобочитаемом, но неточном формате таблицы:
A | B | C | D | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
t_1 | t_2 | t_1 | t_2 | t_1 | t_2 | t_1 | t_2 | ||||||||
x | y | x | y | x | y | x | y | x | y | x | y | x | y | x | y |
1.5 | 6.7 | 8.1 | 7.5 | 2.2 | 5.1 | 3.4 | 1.8 | 6.1 | 2.1 | 9.3 | 7.1 | 8.2 | 1.1 | 1.4 | 2.5 |
4.1 | 5.1 | 7.7 | 4.3 | 7.9 | 3.2 | 1.1 | 5.3 | 8.1 | 0.4 | 2.4 | 4.1 | 9.3 | 3.1 | 0.9 | 3.2 |
Комментарии:
1. Мне было трудно найти правильный синтаксис для сортировки их по элементу строки блоков A,B,C,D. 1. Это выглядит хорошо
2. Я предложу вам использовать этот удивительный инструмент для демонстрации table:tablesgenerator.com/markdown_tables
Ответ №2:
unstack
и groupby
: (единственное решение, которое я могу придумать прямо сейчас)
df1 = df.unstack().unstack()
for col in df1.columns:
a = []
for i,g in df1[col].groupby(level=0):
a.append((i,g.iloc[0]))
get_sortedli = sorted(a, key=lambda x: x[1])
order_col = [f1 for f1,f2 in get_sortedli]
val = (df.iloc[col].reindex(order_col, axis=1, level=0))
df.iloc[col] = val
df:
Я представил себе это как проблему с 4 блоками(A,B,C,D). После упорядочения получите значения и назначьте их реальному кадру данных.
df1:
Комментарии:
1. @Benjamin внесите изменения в добавление
val.index = df1[col].index
— как видите, в этом нет необходимости, результат тот же без этой строки.val
индекс уже таков.