Pandas排序Lambda函数

25

假设有一个包含3列数值的数据框a,列名分别是ABC,有三行数值。如何使用A[i]*B[i]的乘积运算符对所有行进行排序?似乎pandas.sort只能对列进行排序并选择排序方法。
我想使用下面的比较函数。

f = lambda i,j: a['A'][i]*a['B'][i] < a['A'][j]*a['B'][j]
3个回答

26

至少有两种方法:

方法1

假设你从这里开始:

In [175]: df = pd.DataFrame({'A': [1, 2], 'B': [1, -1], 'C': [1, 1]})

您可以添加一个列作为排序键。

In [176]: df['sort_val'] = df.A * df.B

最后按它进行排序并删除它

In [190]: df.sort_values('sort_val').drop('sort_val', 1)
Out[190]: 
   A  B  C
1  2 -1  1
0  1  1  1

方法二

使用numpy.argsort,然后在结果索引上使用.ix

In [197]: import numpy as np

In [198]: df.ix[np.argsort(df.A * df.B).values]
Out[198]: 
   A  B  C
0  1  1  1
1  2 -1  1

那让我找对了方向。谢谢。我发现在子集中需要使用iloc。
df = pd.DataFrame({'A': [10, 2,3,1],'B': [1, -1,-1,3],'C': [1, 1,3,4]}) df A B C 0 10 1 1 1 2 -1 1 2 3 -1 3 3 1 3 4 x = df[(df['A']!=1)] x A B C 0 10 1 1 1 2 -1 1 2 3 -1 3 x.iloc[np.argsort(x.A *x.C).values] A B C 1 2 -1 1 2 3 -1 3 0 10 1 1
- Tom B
4
在不改变原始数据框的情况下,通过一种单个表达式的方法来执行方法一: df.assign(sortval = df.A * df.B).sort_values('sortval').drop('sortval', 1) - kputnam

15

另一种方法,我在这里添加是因为这是Google的第一个结果:

df.loc[(df.A * df.B).sort_values().index]

这对我来说很有效,并且相当简单。 @Ami Tavory的答案在使用分类索引时给了我奇怪的结果; 不确定是不是因为那个原因。


超级优雅!如果您的索引是基于位置而不是基于标签的,我还要提一下df.**iloc**[(df.A * df.B).sort_values().index] - mork

2
最初的回答:在@srs的非常优雅的回答中补充一下,使用iloc选项进行一些时间比较,与loc和朴素解决方案相比较更好(当您的索引是基于位置而非基于标签时,建议使用iloc)。
import numpy as np
import pandas as pd

N = 10000
df = pd.DataFrame({
                   'A': np.random.randint(low=1, high=N, size=N), 
                   'B': np.random.randint(low=1, high=N, size=N)
                  })

%%timeit -n 100
df['C'] = df['A'] * df['B']
df.sort_values(by='C')

naive: 100 loops, best of 3: 1.85 ms per loop

%%timeit -n 100
df.loc[(df.A * df.B).sort_values().index]

loc: 100次循环,3次中最好的结果:每次循环2.69毫秒

%%timeit -n 100
df.iloc[(df.A * df.B).sort_values().index]

iloc: 100 loops, best of 3: 2.02 ms per loop

df['C'] = df['A'] * df['B']

df1 = df.sort_values(by='C')
df2 = df.loc[(df.A * df.B).sort_values().index]
df3 = df.iloc[(df.A * df.B).sort_values().index]

print np.array_equal(df1.index, df2.index)
print np.array_equal(df2.index, df3.index)

比较所有选项之间的测试结果(比较整个索引顺序):

最初的回答

最初的回答


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接