我有两个高级排序场景。
它们是独立的案例,因此我在下面列出了具有预期结果的示例。
import pandas as pd
a={
"ip":['10.10.11.30','10.10.11.30','10.10.11.30', '10.2.2.10', '10.10.2.1', '10.2.2.2'],
"path":['/data/foo/err','/data/foo/zone','/data/foo/err','/data/foo/zone','/data/foo/zone','/data/foo/tmp'],
"date":['25/01/2024','25/01/2024','01/08/2020','23/01/2024','24/01/2024','25/01/2024'],
"count":[3,10,20,5,20,50]
}
df=pd.DataFrame(a)
print(df)
print()
## Output
ip path date count
0 10.10.11.30 /data/foo/err 25/01/2024 3
1 10.10.11.30 /data/foo/zone 25/01/2024 10
2 10.10.11.30 /data/foo/err 01/08/2020 20
3 10.2.2.10 /data/foo/zone 23/01/2024 5
4 10.10.2.1 /data/foo/zone 24/01/2024 20
5 10.2.2.2 /data/foo/tmp 25/01/2024 50
可运行示例:https://onecompiler.com/python/422hhyqa5
ip path date count
5 10.2.2.2 /data/foo/tmp 25/01/2024 50
3 10.2.2.10 /data/foo/zone 23/01/2024 5
4 10.10.2.1 /data/foo/zone 24/01/2024 20
2 10.10.11.30 /data/foo/err 01/08/2020 20
0 10.10.11.30 /data/foo/err 25/01/2024 3
1 10.10.11.30 /data/foo/zone 25/01/2024 10
对多列执行“自然”排序非常简单(日期为 DateTime 类型)。
我还成功实现了按ip排序
但是我没能将两者结合起来,因为它总是给出不同的错误
df_sorted_by_date = (df.sort_values(by=['date', 'count'],
ascending=[True, True],
ignore_index=True)
df_sorted_by_ip = (df.sort_values(by=["ip"],
key=lambda x: x.str.split(".").apply(lambda y: [int(z) for z in y]),
ignore_index=True))
rank1
:如果 (path contains 'zone') and (count >=10)
则排名第一并按 IP ASC
rank2
:如果 (path NOT contains 'zone') and (count >=10) and (date = today())
则排名第二并按 IP ASC
rank3
:剩余的行放在最后,并按 IP ASC
排序,然后按 date ASC
(如果值相等)假设今天是 25 号
ip path date count
4 10.10.2.1 /data/foo/zone 24/01/2024 20 # rank1
1 10.10.11.30 /data/foo/zone 25/01/2024 10 # rank1
5 10.2.2.2 /data/foo/tmp 25/01/2024 50 # rank2
3 10.2.2.10 /data/foo/zone 23/01/2024 5 # rank3
2 10.10.11.30 /data/foo/err 01/08/2020 20 # rank3
0 10.10.11.30 /data/foo/err 25/01/2024 3 # rank3
没有。我不知道如何继续,这对我来说非常先进>_<
分配使用
numpy.select
计算的排名并使用 natsort
执行自然排序:
from natsort import natsort_key
df['date'] = pd.to_datetime(df['date'], dayfirst=True)
m1 = df['path'].str.contains('zone')
m2 = df['count'].ge(10)
m3 = df['date'].eq(pd.Timestamp('25/01/2024'))
df['rank'] = np.select([m1&m2, m2&m3&~m1],
['rank1', 'rank2'],
'rank3')
out = df.sort_values(by=['rank', 'ip', 'date', 'count'], key=natsort_key)
输出:
ip path date count rank
4 10.10.2.1 /data/foo/zone 2024-01-24 20 rank1
1 10.10.11.30 /data/foo/zone 2024-01-25 10 rank1
5 10.2.2.2 /data/foo/tmp 2024-01-25 50 rank2
3 10.2.2.10 /data/foo/zone 2024-01-23 5 rank3
2 10.10.11.30 /data/foo/err 2020-08-01 20 rank3
0 10.10.11.30 /data/foo/err 2024-01-25 3 rank3