Pandas 排序多索引数据透视表
要按其值对数据轴进行排序Pandas 排序多索引数据透视表,pandas,pivot-table,Pandas,Pivot Table,要按其值对数据轴进行排序 data = {'Counterparty': {0: 'A', 1: 'B', 2: 'B', 3: 'A', 4: 'A', 5: 'C', 6: 'D', 7: 'E', 8: 'E', 9: 'C', 10: 'F', 11: 'C', 12: 'C', 13: 'G'}, 'Contract': {0: 'A1', 1: 'B1', 2: 'B2', 3: 'A2', 4: 'A3',
data = {'Counterparty': {0: 'A',
1: 'B',
2: 'B',
3: 'A',
4: 'A',
5: 'C',
6: 'D',
7: 'E',
8: 'E',
9: 'C',
10: 'F',
11: 'C',
12: 'C',
13: 'G'},
'Contract': {0: 'A1',
1: 'B1',
2: 'B2',
3: 'A2',
4: 'A3',
5: 'C1',
6: 'D1',
7: 'E1',
8: 'E2',
9: 'C2',
10: 'F1',
11: 'C3',
12: 'C4',
13: 'G'},
'Delivery': {0: '1/8/2019',
1: '1/8/2019',
2: '1/8/2019',
3: '1/8/2019',
4: '1/8/2019',
5: '1/8/2019',
6: '1/8/2019',
7: '1/8/2019',
8: '1/8/2019',
9: '1/8/2019',
10: '1/8/2019',
11: '1/8/2019',
12: '1/8/2019',
13: '1/8/2019'},
'Price': {0: 134.0,
1: 151.0,
2: 149.0,
3: 134.0,
4: 132.14700000000002,
5: 150.0,
6: 134.566,
7: 153.0,
8: 151.0,
9: 135.0,
10: 149.0,
11: 135.0,
12: 147.0,
13: 151.0},
'Balance': {0: 200.0,
1: 54.87,
2: 200.0,
3: 133.44,
4: 500.0,
5: 500.0,
6: 1324.05,
7: 279.87,
8: 200.0,
9: 20.66,
10: 110.15,
11: 100.0,
12: 100.0,
13: 35.04}}
从数据获取df:
df=pd.DataFrame(数据)
定义用于计算价格加权平均值的函数
wa = lambda x: np.average(x, weights=df.loc[x.index, 'Balance'])
pivot = df.pivot_table(
index=['Counterparty', 'Contract'],
columns='Delivery',
values=['Balance', 'Price'],
aggfunc={
'Balance': sum,
'Price': wa
},
margins=True
).fillna('').swaplevel(0,1,axis=1).sort_index(axis=1).round(3)
结果:
Delivery 1/8/2019 1/9/2019 All
Balance Price Balance Price Balance Price
Counterparty Contract
A A1 200 134 200.00 134.000
A2 133.44 134 133.44 134.000
A3 500 132.147 500.00 132.147
B B1 54.87 151 54.87 151.000
B2 200 149 200.00 149.000
C C1 500 150 500.00 150.000
C2 20.66 135 20.66 135.000
C3 100 135 100.00 135.000
C4 100 147 100.00 147.000
D D1 1324.05 134.566 1324.05 134.566
E E1 279.87 153 279.87 153.000
E2 200 151 200.00 151.000
F F1 110.15 149 110.15 149.000
G G 35.04 151 35.04 151.000
All 2313.37 143.541 1444.71 135.433 3758.08 140.424
检查列顺序的多索引:
MultiIndex([('1/8/2019', 'Balance'),
('1/8/2019', 'Price'),
('1/9/2019', 'Balance'),
('1/9/2019', 'Price'),
( 'All', 'Balance'),
( 'All', 'Price')],
name=['Delivery', 'None'])
重命名多索引并尝试通过传入包含元组的列表进行排序(引用:):
结果导致一个键错误
预期结果:
Delivery 1/8/2019 1/9/2019 All
Balance Price Balance Price Balance Price
Counterparty Contract
C C1 500 150 500.00 150.000
A A3 500 132.147 500.00 132.147
E E1 279.87 153 279.87 153
...
首先删除
fillna
以避免数值和字符串的混合,然后按从MultiIndex
创建的元组排序,而不是按MultiIndex.columns.names
排序。最后一行如果需要All
行到最后一行添加:
如果需要按所有列进行排序:
df = pivot.sort_values(by=pivot.columns.tolist(), ascending=False)
df = pd.concat([df.iloc[1:], df.iloc[[0]]])
print (df)
Delivery 1/8/2019 1/9/2019 All
Balance Price Balance Price Balance Price
Counterparty Contract
C C1 500.00 150.000 NaN NaN 500.00 150.000
A A3 500.00 132.147 NaN NaN 500.00 132.147
E E1 279.87 153.000 NaN NaN 279.87 153.000
E2 200.00 151.000 NaN NaN 200.00 151.000
B B2 200.00 149.000 NaN NaN 200.00 149.000
A A1 200.00 134.000 NaN NaN 200.00 134.000
A2 133.44 134.000 NaN NaN 133.44 134.000
F F1 110.15 149.000 NaN NaN 110.15 149.000
C C3 100.00 135.000 NaN NaN 100.00 135.000
B B1 54.87 151.000 NaN NaN 54.87 151.000
G G 35.04 151.000 NaN NaN 35.04 151.000
D D1 NaN NaN 1324.05 134.566 1324.05 134.566
C C4 NaN NaN 100.00 147.000 100.00 147.000
C2 NaN NaN 20.66 135.000 20.66 135.000
All 2313.37 143.541 1444.71 135.433 3758.08 140.424
非常感谢@jezrael。。我现在了解了如何使用多索引中的元组对列进行排序。。但是,在对整个df(还有几个月)进行排序时,有些月份排序不正确。你介意我们继续聊天吗?@yongsheng-当然,你能邀请我吗?
df = pd.DataFrame(data)
#print (df)
wa = lambda x: np.average(x, weights=df.loc[x.index, 'Balance'])
pivot = df.pivot_table(
index=['Counterparty', 'Contract'],
columns='Delivery',
values=['Balance', 'Price'],
aggfunc={
'Balance': sum,
'Price': wa
},
margins=True
).swaplevel(0,1,axis=1).sort_index(axis=1).round(3)
pivot.columns.name = ['Delivery', 'Metrics']
df = pivot.sort_values(by=[('1/8/2019', 'Balance'), ('1/8/2019', 'Price')], ascending=False)
df = pd.concat([df.iloc[1:], df.iloc[[0]]])
print (df)
Delivery 1/8/2019 1/9/2019 All
Balance Price Balance Price Balance Price
Counterparty Contract
C C1 500.00 150.000 NaN NaN 500.00 150.000
A A3 500.00 132.147 NaN NaN 500.00 132.147
E E1 279.87 153.000 NaN NaN 279.87 153.000
E2 200.00 151.000 NaN NaN 200.00 151.000
B B2 200.00 149.000 NaN NaN 200.00 149.000
A A1 200.00 134.000 NaN NaN 200.00 134.000
A2 133.44 134.000 NaN NaN 133.44 134.000
F F1 110.15 149.000 NaN NaN 110.15 149.000
C C3 100.00 135.000 NaN NaN 100.00 135.000
B B1 54.87 151.000 NaN NaN 54.87 151.000
G G 35.04 151.000 NaN NaN 35.04 151.000
C C2 NaN NaN 20.66 135.000 20.66 135.000
C4 NaN NaN 100.00 147.000 100.00 147.000
D D1 NaN NaN 1324.05 134.566 1324.05 134.566
All 2313.37 143.541 1444.71 135.433 3758.08 140.424
df = pivot.sort_values(by=pivot.columns.tolist(), ascending=False)
df = pd.concat([df.iloc[1:], df.iloc[[0]]])
print (df)
Delivery 1/8/2019 1/9/2019 All
Balance Price Balance Price Balance Price
Counterparty Contract
C C1 500.00 150.000 NaN NaN 500.00 150.000
A A3 500.00 132.147 NaN NaN 500.00 132.147
E E1 279.87 153.000 NaN NaN 279.87 153.000
E2 200.00 151.000 NaN NaN 200.00 151.000
B B2 200.00 149.000 NaN NaN 200.00 149.000
A A1 200.00 134.000 NaN NaN 200.00 134.000
A2 133.44 134.000 NaN NaN 133.44 134.000
F F1 110.15 149.000 NaN NaN 110.15 149.000
C C3 100.00 135.000 NaN NaN 100.00 135.000
B B1 54.87 151.000 NaN NaN 54.87 151.000
G G 35.04 151.000 NaN NaN 35.04 151.000
D D1 NaN NaN 1324.05 134.566 1324.05 134.566
C C4 NaN NaN 100.00 147.000 100.00 147.000
C2 NaN NaN 20.66 135.000 20.66 135.000
All 2313.37 143.541 1444.71 135.433 3758.08 140.424