2013-07-12 75 views
44

我有以下的数据帧:如何使用来自多列的值对熊猫数据框进行排序?

df = pandas.DataFrame([{'c1':3,'c2':10},{'c1':2, 'c2':30},{'c1':1,'c2':20},{'c1':2,'c2':15},{'c1':2,'c2':100}]) 

或者,在人类可读的形式:

c1 c2 
0 3 10 
1 2 30 
2 1 20 
3 2 15 
4 2 100 

以下排序命令按预期工作:

df.sort(['c1','c2'], ascending=False) 

输出:

c1 c2 
0 3 10 
4 2 100 
1 2 30 
3 2 15 
2 1 20 

但下面的命令:

df.sort(['c1','c2'], ascending=[False,True]) 

结果

c1 c2 
2 1 20 
3 2 15 
1 2 30 
4 2 100 
0 3 10 

,这不是我所期望的。我期望第一列中的值从最大到最小排列,如果第一列中有相同的值,则按第二列中的升序值排序。

有谁知道为什么它不能按预期工作?

ADDED

这是复制粘贴:

>>> df.sort(['c1','c2'], ascending=[False,True]) 
    c1 c2 
2 1 20 
3 2 15 
1 2 30 
4 2 100 
0 3 10 
+0

您使用的是什么版本的熊猫和numpy? –

回答

42

您的代码为我工作。

>>> import pandas 
>>> df = pandas.DataFrame([{'c1':3,'c2':10},{'c1':2, 'c2':30},{'c1':1,'c2':20},{'c1':2,'c2':15},{'c1':2,'c2':100}]) 
>>> df.sort(['c1','c2'], ascending=[False,True]) 
    c1 c2 
0 3 10 
3 2 15 
1 2 30 
4 2 100 
2 1 20 

你粘贴为是?

>>> df.sort(['c1','c2'], ascending=[True,True]) 
    c1 c2 
2 1 20 
3 2 15 
1 2 30 
4 2 100 
0 3 10 

UPDATEDataFrame.sort已弃用;使用DataFrame.sort_values

>>> df.sort(['c1','c2'], ascending=[False,True]) 
__main__:1: FutureWarning: sort(columns=....) is deprecated, use sort_values(by=.....) 
    c1 c2 
0 3 10 
3 2 15 
1 2 30 
4 2 100 
2 1 20 
>>> df.sort_values(['c1','c2'], ascending=[False,True]) 
    c1 c2 
0 3 10 
3 2 15 
1 2 30 
4 2 100 
2 1 20 
+0

建议:与底部原件相反的顺序,更新顶部。自上而下阅读我尝试第一个模块,并想知道为什么它失败了,被“它适用于我”和“你粘贴的原因”倍加混淆(当然,这是我的错!)。然后我滚动,看到更新... – Hendy

2

如果你正在写这个代码的脚本文件,那么你必须把它写这样的:

df = df.sort(['c1','c2'], ascending=[False,True]) 
21

使用sort可能导致警告消息。见github讨论。 所以,你可能想使用sort_values,文档here

然后你的代码可以是这样的:

df = df.sort_values(by=['c1','c2'], ascending=[False,True]) 
+0

否则我会收到警告'/Applications/anaconda/lib/python2.7/site-packages/spyderlib/widgets/externalshell/start_ipython_kernel.py:1:FutureWarning:sort(columns = ....)已弃用,请使用sort_values(by = .....)' – abhiieor

+0

@patapouf_ai不,现在不推荐使用'sort' – oulenz

1

我发现这是非常有用的:

df = pd.DataFrame({'A' : range(0,10) * 2, 'B' : np.random.randint(20,30,20)}) 

# A ascending, B descending 
df.sort(**skw(columns=['A','-B'])) 

# A descending, B ascending 
df.sort(**skw(columns=['-A','+B'])) 

注意与标准columns=,ascending=参数,这里的列名和它们的排序顺序在同一个地方。因此,您的代码更易于阅读和维护。

注到.sort实际调用是不变的,skw小号 ORT千瓦参数)是只是一个小的辅助函数解析列,并返回通常columns=ascending=参数为您服务。像通常那样传递任何其他类型的kwargs。将以下代码复制/粘贴到您的本地utils.py然后忘掉它,并只是像上面那样使用它。

# utils.py (or anywhere else convenient to import) 
def skw(columns=None, **kwargs): 
    """ get sort kwargs by parsing sort order given in column name """ 
    # set default order as ascending (+) 
    sort_cols = ['+' + col if col[0] != '-' else col for col in columns] 
    # get sort kwargs 
    columns, ascending = zip(*[(col.replace('+', '').replace('-', ''), 
           False if col[0] == '-' else True) 
           for col in sort_cols]) 
    kwargs.update(dict(columns=list(columns), ascending=ascending)) 
    return kwargs 
+2

与其他选项相比,这看起来像是过度杀毒。 – digitaldavenyc

+0

只看这个例子,而不是'sortkwargs'函数。这是一种一次性的定义,您可以将其从您的存储库中导出并导入。 'util.py'。与默认的'sort'语法相比,您的代码将更具灵活性和可读性。 – miraculixx

+0

投下全部你喜欢的,请添加评论,这样我就可以改进答案了 – miraculixx

7

的dataframe.sort()方法是 - 所以我的理解 - 在熊猫> 0.18弃用。为了解决您的问题,您应该使用dataframe.sort_values()代替:

f.sort_values(by=["c1","c2"], ascending=[False, True]) 

输出看起来是这样的:

c1 c2 
    3 10 
    2 15 
    2 30 
    2 100 
    1 20 
4

在我的情况下,接受的答案没有工作:

f.sort_values(由= [ “C1”, “C2”],上升= [假,真])

只有按预期以下工作:

f = f.sort_values(by=["c1","c2"], ascending=[False, True]) 
+2

认真?你知道熊猫有一种叫做[inplace]的东西(http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sort.html) – Hng

相关问题