#python #pandas #multi-index
#python #панды #многоиндексный
Вопрос:
Я хочу отсортировать фрейм данных от наивысшего к наименьшему на основе столбца B. Я не могу найти ответ о том, как сортировать внешний (т. Е. Первый) столбец индекса.
У меня есть этот пример данных:
A B
Item Type
0 X 'rtr' 2
Tier 'sfg' 104
1 X 'zad' 7
Tier 'asd' 132
2 X 'frs' 4
Tier 'plg' 140
3 X 'gfq' 9
Tier 'bcd' 100
Каждая строка с несколькими индексами содержит строку «Уровня». Я хочу отсортировать внешний индексный «Элемент» на основе значения столбца «B», относящегося к каждому «Уровню». Столбец «A» можно игнорировать для целей сортировки, но его необходимо включить в фрейм данных.
A B
Item Type
2 X 'frs' 4
Tier 'plg' 140
1 X 'zad' 7
Tier 'asd' 132
0 X 'rtr' 2
Tier 'sfg' 104
3 X 'gfq' 9
Tier 'bcd' 100
Комментарии:
1. используйте
.sort_values('A')
перед.groupby()
. Он также будет отсортирован2. можете ли вы поделиться своими необработанными данными, чтобы мы могли попытаться решить проблему сортировки.
3. Конечно, вот необработанные данные в формате CSV: pastebin.com/raw/8nJnURk7 Столбец «Итого» представляет собой букву «В» в этом вопросе. Индексы «Item» и «Type» и строка «Tier» имеют одно и то же имя, чтобы было понятно, в этом случае элементы 2, 4, 7 должны быть вверху (поскольку общие значения уровня равны 23), а элементы 0, 1, 3, 5, 6 должны быть внизу(поскольку общие значения уровня равны 22)
4. Итак, вы хотите отсортировать по элементу, затем по «B», а затем по «Типу». Правильно? Если да, то не
0
будет ли это первым элементом в списке? В качестве альтернативы, если вы хотите отсортировать по B, затем по элементу, тогда введите, не будет ли 2 в ‘B’ первым элементом, чтобы фрейм данных сортировался по элементу как 0, затем 2, затем 1, затем 75. Нет, это должно быть 2, 1, 0, 3. Строка (элемент) полного / внешнего индекса должна перемещаться выше или ниже в зависимости от ее значения в столбце B только для строки уровня. Причина, по которой я сформулировал вопрос таким образом, заключалась в том, что я видел предыдущий вопрос, в котором предлагается перемещать только строки внутреннего индекса (сохраняя при этом порядок первого / внешнего индекса одинаковым)
Ответ №1:
Новый ответ # 2
На основе всех полученных входных данных, вот решение. Надеюсь, это сработает для вас.
import pandas as pd
df = pd.read_csv("xyz.txt")
df1 = df.copy()
#capture the original index of each row. This will be used for sorting later
df1['idx'] = df1.index
#create a dataframe with only items that match 'Tier'
#assumption is each Index has a row with 'Tier'
tier = df1.loc[df1['Type']=='Tier']
#sort Total for only the Tier rows
tier = tier.sort_values('Total')
#Create a list of the indexes in sorted order
#this will be the order to print the rows
tier_list = tier['Index'].tolist()
# Create the dictionary that defines the order for sorting
sorterIndex = dict(zip(tier_list, range(len(tier_list))))
# Generate a rank column that will be used to sort the dataframe numerically
df1['Tier_Rank'] = df1['Index'].map(sorterIndex)
#Now sort the dataframe based on rank column and original index
df1.sort_values(['Tier_Rank','idx'],ascending = [True, True],inplace = True)
#drop the temporary column we created
df1.drop(['Tier_Rank','idx'], 1, inplace = True)
#print the dataframe
print (df1)
На основе исходных данных, вот окончательный результат. Дайте мне знать, соответствует ли это тому, что вы искали.
Index Type Id ... Intellect Strength Total
12 2 Chest Armor "6917529202229928161" ... 17 8 62
13 2 Gauntlets "6917529202229927889" ... 16 14 60
14 2 Helmet "6917529202223945870" ... 10 9 66
15 2 Leg Armor "6917529202802011569" ... 15 2 61
16 2 Set NaN ... 58 33 249
17 2 Tier NaN ... 5 3 22
24 4 Chest Armor "6917529202229928161" ... 17 8 62
25 4 Gauntlets "6917529202802009244" ... 7 9 63
26 4 Helmet "6917529202223945870" ... 10 9 66
27 4 Leg Armor "6917529202802011569" ... 15 2 61
28 4 Set NaN ... 49 28 252
29 4 Tier NaN ... 4 2 22
42 7 Chest Armor "6917529202229928161" ... 17 8 62
43 7 Gauntlets "6917529202791088503" ... 7 14 61
44 7 Helmet "6917529202223945870" ... 10 9 66
45 7 Leg Armor "6917529202229923870" ... 7 19 57
46 7 Set NaN ... 41 50 246
47 7 Tier NaN ... 4 5 22
0 0 Chest Armor "6917529202229928161" ... 17 8 62
1 0 Gauntlets "6917529202778947311" ... 10 15 62
2 0 Helmet "6917529202223945870" ... 10 9 66
3 0 Leg Armor "6917529202802011569" ... 15 2 61
4 0 Set NaN ... 52 34 251
5 0 Tier NaN ... 5 3 23
6 1 Chest Armor "6917529202229928161" ... 17 8 62
7 1 Gauntlets "6917529202778947311" ... 10 15 62
8 1 Helmet "6917529202223945870" ... 10 9 66
9 1 Leg Armor "6917529202229923870" ... 7 19 57
10 1 Set NaN ... 44 51 247
11 1 Tier NaN ... 4 5 23
18 3 Chest Armor "6917529202229928161" ... 17 8 62
19 3 Gauntlets "6917529202229927889" ... 16 14 60
20 3 Helmet "6917529202223945870" ... 10 9 66
21 3 Leg Armor "6917529202229923870" ... 7 19 57
22 3 Set NaN ... 50 50 245
23 3 Tier NaN ... 5 5 23
30 5 Chest Armor "6917529202229928161" ... 17 8 62
31 5 Gauntlets "6917529202802009244" ... 7 9 63
32 5 Helmet "6917529202223945870" ... 10 9 66
33 5 Leg Armor "6917529202229923870" ... 7 19 57
34 5 Set NaN ... 41 45 248
35 5 Tier NaN ... 4 4 23
36 6 Chest Armor "6917529202229928161" ... 17 8 62
37 6 Gauntlets "6917529202791088503" ... 7 14 61
38 6 Helmet "6917529202223945870" ... 10 9 66
39 6 Leg Armor "6917529202802011569" ... 15 2 61
40 6 Set NaN ... 49 33 250
41 6 Tier NaN ... 4 3 23
[48 rows x 11 columns]
Новый ответ:
На основе общего файла исходных данных, вот группировка и сортировка. Дайте мне знать, как вы хотите, чтобы значения были отсортированы. Я предположил, что вы хотите, чтобы он был отсортирован по индексу, а затем по сумме.
df = df.groupby(['Index','Type',])
.agg({'Total':'mean'})
.sort_values(['Index','Total'])
Результат этого будет следующим:
Total
Index Type
0 Tier 23
Leg Armor 61
Chest Armor 62
Gauntlets 62
Helmet 66
Set 251
1 Tier 23
Leg Armor 57
Chest Armor 62
Gauntlets 62
Helmet 66
Set 247
2 Tier 22
Gauntlets 60
Leg Armor 61
Chest Armor 62
Helmet 66
Set 249
3 Tier 23
Leg Armor 57
Gauntlets 60
Chest Armor 62
Helmet 66
Set 245
4 Tier 22
Leg Armor 61
Chest Armor 62
Gauntlets 63
Helmet 66
Set 252
Первоначальный ответ:
У меня нет ваших необработанных данных. Создал некоторые данные, чтобы показать вам, как сортировка будет работать с данными groupby. Посмотрите, это ли то, что вы ищете.
импортируйте pandas как pd
df = pd.DataFrame({'Animal': ['Falcon', 'Falcon','Parrot', 'Parrot'],
'Type':['Wild', 'Captive', 'Wild', 'Captive'],
'Air': ['Good','Bad', 'Bad', 'Good'],
'Max Speed': [380., 370., 24., 26.]})
df = df.groupby(['Animal','Type','Air'])
.agg({'Max Speed':'mean'})
.sort_values('Max Speed')
print(df)
Результат будет следующим:
Max Speed
Animal Type Air
Parrot Wild Bad 24.0
Captive Good 26.0
Falcon Captive Bad 370.0
Wild Good 380.0
Без команды сортировки результат будет немного отличаться.
df = df.groupby(['Animal','Type','Air'])
.agg({'Max Speed':'mean'})
Это приведет к следующему. Максимальная скорость не сортируется. Вместо этого он использует группу по виду животного, а затем вводит:
Max Speed
Animal Type Air
Falcon Captive Bad 370.0
Wild Good 380.0
Parrot Captive Good 26.0
Wild Bad 24.0
Комментарии:
1. Порядок строк в «типе» должен оставаться таким же, как и в оригинале. Должна измениться только позиция индекса (в зависимости от значения уровня в общем столбце). Также другой столбец «A» должен оставаться в dataframe. Таким образом, 0, 1 и 3 должны быть вверху, потому что они имеют самые высокие уровни (23), в то время как 2 и 4 должны быть внизу (имеют только уровни 22)