2013-07-12 105 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

相關問題