我想先对 b 列上的以下 DataFrame 进行排序,然后对 a 列进行排序。
a | b |
---|---|
0 | 1.2 |
2 | 0.07076863960397785 |
1 | 0.07076863960397783 |
4 | 0.02 |
应使用 math.isclose() 函数来比较 b 列中的浮点数。因此,我编写了一个自定义比较函数并使用 functools 中的 cmp_to_key 函数。但是,在对数据框进行排序时,出现以下错误:
TypeError:“functools.KeyWrapper”类型的对象没有 len()
这是我的完整代码:
import pandas as pd
from functools import cmp_to_key
from math import isclose
import numpy as np
my_list = [
[0, 1.2],
[2, 0.07076863960397785],
[1, 0.07076863960397783],
[4, 0.02],
[3, 0.07076863960397784]
]
df = pd.DataFrame(my_list,columns=['a','b'])
def compare(a,b):
if isclose(a,b):
return 0
elif a-b<0:
return -1
else:
return 1
df.sort_values(by=['b','a'],key= cmp_to_key(compare))
现在,我知道 sort_values 中的键需要一个序列,因此键函数应该被向量化。但我不知道如何实现这一点。
这应该是最终结果:
a | b |
---|---|
4 | 0.02 |
1 | 0.07076863960397783 |
2 | 0.07076863960397785 |
0 | 1.2 |
您可以将
sort_values()
与 np.argsort()
一起使用:
import pandas as pd
import numpy as np
from math import isclose
from functools import cmp_to_key
def _sort(df):
compare = lambda a, b: 0 if isclose(a, b) else (-1 if a < b else 1)
inds = sorted(range(len(df)), key=cmp_to_key(lambda i, j: compare(df.at[i, 'b'], df.at[j, 'b'])))
df = df.iloc[inds].reset_index(drop=True)
df = df.sort_values(by=['b', 'a'], key=lambda col: np.argsort(col))
return df
my_list = [
[0, 1.2],
[2, 0.07076863960397785],
[1, 0.07076863960397783],
[4, 0.02],
[3, 0.07076863960397784]
]
df = pd.DataFrame(my_list, columns=['a', 'b'])
print(_sort(df))
a b
0 4 0.020000
3 3 0.070769
1 2 0.070769
2 1 0.070769
4 0 1.200000