pandas sort_values 原理 排序异常 行上下关系改变 多列排序解决

https://download.csdn.net/download/weixin_43256057/80827998

import pandas as pd
import numpy as np
qualDe = pd.read_excel('t1.xlsx',engine='openpyxl')
num = 'U06211002309'
df = qualDe[qualDe.col1.str.contains(num)]
df
				col1	col2
2700	U06211002309	2.0
2701	U06211002309A	1.0
2702	U06211002309B	2.0
2703	U06211002309C	NaN
2704	U06211002309D	1.0
2705	U06211002309E	NaN
2706	U06211002309F	1.0

对col2排序后又让有序的col1行变回原来的上下关系(同col2数值下维持col1顺序不变)

# 要想让col2降序同时又在同数值中保持col1的上下顺序不变,目前是做不到了,但如果原来col1的顺序就是有序的,那么可以通过重新排序让它恢复到原来的上下关系的样子。就如
# 不可能把从被子中倒掉的水做时间倒流让它变回没倒水的状态(无法改变必定发生的动作),但可以通过重新给杯子装同样多的水让它看起来和之前一样。
df3 = qualDe.sort_values(by=['col2','col1'],ascending=[False,True])
df3[df3.col1.str.contains(num)]

				col1	col2
2700	U06211002309	2.0
2702	U06211002309B	2.0
2701	U06211002309A	1.0
2704	U06211002309D	1.0
2706	U06211002309F	1.0
2703	U06211002309C	NaN
2705	U06211002309E	NaN
qe = df[df.col2>0].sort_values(by=['col2'],ascending=[False])
qe[qe.col1.str.contains(num)] 
# 我发现一旦先选定df = qualDe[qualDe.col1.str.contains(num)],接下来的排序就会比较正常,初步猜测原因不是Python排序问题,而是有数据干扰。
				col1	col2
2700	U06211002309	2.0
2702	U06211002309B	2.0
2701	U06211002309A	1.0
2704	U06211002309D	1.0
2706	U06211002309F	1.0
dfa = qualDe.sort_values('col2')
dfa[dfa.col1.str.contains(num)] # 从下往上读,对无法排序的不管,把能排序且最小的往顶部插入,依次往上,形成这个col2降序但col1却顺序颠倒的状况。
				col1	col2
2706	U06211002309F	1.0
2704	U06211002309D	1.0
2701	U06211002309A	1.0
2702	U06211002309B	2.0
2700	U06211002309	2.0
2703	U06211002309C	NaN
2705	U06211002309E	NaN
pd.set_option('display.max_rows',None)
df1 = qualDe[qualDe.col2>0].sort_values('col2',ascending=False).reset_index().drop('index',axis=1)
df2 = df1[df1.col1.str.contains(num)] # 可看出他们之间是有被其它数据渗入的。
df1[(df2.index[0]<=df1.index) & (df1.index<=df2.index[-1])] # U06211002309B 本应紧挨在U06211002309下面,结果却跑到它上面去了,中间夹杂index=5~10的记录。
# 我猜测sort_values 把超过一定长度的数组一律先归类分组,对各组非NaN(无法排序的)的分别把每7~10个相同的最大(ascending=False)/最小(ascending=True)元素插入
# 最顶端,导致相同值的行上下关系颠倒。但对长度太短的(比如上面qe.col1.str.contains(num))就直接采取冒泡排序(相邻元素做比较看是否要互换位置,网上说的
# Python sort原理挺复杂的),相同值的行上下关系不变。这样才能解释col2相同的数值,col1有数值的似乎都是分组后各自颠倒(9B>9,9F>9D>9A)。

			col1	col2
4	U06211002309B	2.0
5	U06210911308A	2.0
6	X87211001001B	2.0
7	U01211016604	2.0
8	U06211016338	2.0
9	H50210814001B	2.0
10	A67210822008	2.0
11	U06211002309	2.0
12	Y77211104048	1.0
13	T06211104005	1.0
14	U02211030405	1.0
15	U02211030403	1.0
16	U06211030308A	1.0
17	T06211104003	1.0
18	U06211030309	1.0
19	U06211030338	1.0
20	U06211030388	1.0
21	U06211030368	1.0
22	Y68211103888	1.0
23	A127211030030	1.0
24	Y68211105003	1.0
25	Y68211105005	1.0
26	A59211030002	1.0
27	U05211030888	1.0
28	A59211030008	1.0
29	A28211105007	1.0
30	U01211030333	1.0
31	U01211030407	1.0
32	U01211030037	1.0
33	U01211030027	1.0
34	U01211030007	1.0
35	M04211031673	1.0
36	T06211102002	1.0
37	M04211030672	1.0
38	A28211105075	1.0
39	A28211105005	1.0
40	B88211030388	1.0
41	S56211105087	1.0
42	A28211105788	1.0
43	Y68211105887	1.0
44	U03211030674	1.0
45	A27211102888	1.0
46	U06211016338A	1.0
47	A67211030123	1.0
48	Y68210924777	1.0
49	U02210918415A	1.0
50	E87210916999E	1.0
51	E15210910777B	1.0
52	U03210904160B	1.0
53	U03210904160A	1.0
54	U03210904153	1.0
55	U03210904103	1.0
56	U02210904416	1.0
57	V02210904018F	1.0
58	P48210911829G	1.0
59	P99210903503E	1.0
60	C29210825789A	1.0
61	A86210821008	1.0
62	A67210822008A	1.0
63	A27210821001	1.0
64	C29210923103	1.0
65	Y68210924777B	1.0
66	U02211023400	1.0
67	U02210925446A	1.0
68	B98211030102	1.0
69	U06211016338B	1.0
70	U03211016307	1.0
71	U03211016306C	1.0
72	U03211016300	1.0
73	U01211016604F	1.0
74	P77211021001F	1.0
75	U06211009388A	1.0
76	U02211009421A	1.0
77	A59211009009	1.0
78	E87211004951	1.0
79	U06211002309F	1.0
80	U06211002309D	1.0
81	U06211002309A	1.0

要写这篇文章主要目的是发现Python的数组排序方法并不是像我们常人想象的那样根据某列数据做整体数组平移,而是用了更复杂的排序方法,导致该列相同值中,行之间原本上下层关系被改变到甚至是完全分组颠倒过来。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值