วิธีการเรียงลำดับ dataFrame ใน python pandas โดยคอลัมน์สองคอลัมน์ขึ้นไป


255

สมมติว่าฉันมี dataframe กับคอลัมน์a, bและcผมต้องการที่จะจัดเรียง dataframe จากคอลัมน์bใน Ascending Order และคอลัมน์cในลำดับถัดลงฉันจะทำเช่นนี้?


ตรวจสอบคำตอบนี้stackoverflow.com/a/14946246/1948860
richie

คำตอบ:


455

ในฐานะของ 0.17.0 ปล่อยที่วิธีการได้รับการยกเลิกในความโปรดปรานของ sort ถูกลบอย่างสมบูรณ์ในรุ่น 0.20.0 อาร์กิวเมนต์ (และผลลัพธ์) ยังคงเหมือนเดิม:sort_valuessort

df.sort_values(['a', 'b'], ascending=[True, False])

คุณสามารถใช้อาร์กิวเมนต์จากน้อยไปมากsort:

df.sort(['a', 'b'], ascending=[True, False])

ตัวอย่างเช่น:

In [11]: df1 = pd.DataFrame(np.random.randint(1, 5, (10,2)), columns=['a','b'])

In [12]: df1.sort(['a', 'b'], ascending=[True, False])
Out[12]:
   a  b
2  1  4
7  1  3
1  1  2
3  1  2
4  3  2
6  4  4
0  4  3
9  4  3
5  4  1
8  4  1

ตามที่แสดงความคิดเห็นโดย @renadeen

การเรียงลำดับไม่ได้อยู่ในตำแหน่งตามค่าเริ่มต้น! ดังนั้นคุณควรกำหนดผลลัพธ์ของวิธีการเรียงลำดับให้กับตัวแปรหรือเพิ่ม inplace = True เพื่อเรียกเมธอด

นั่นคือถ้าคุณต้องการใช้ df1 ซ้ำเป็น DataFrame ที่เรียงลำดับ:

df1 = df1.sort(['a', 'b'], ascending=[True, False])

หรือ

df1.sort(['a', 'b'], ascending=[True, False], inplace=True)

7
การเรียงลำดับไม่ได้อยู่ในตำแหน่งตามค่าเริ่มต้น! ดังนั้นคุณควรกำหนดผลลัพธ์ของsortเมธอดให้กับตัวแปรหรือเพิ่มinplace=Trueไปยังการเรียกเมธอด
renadeen

2
@renadeen เป็นจุดที่ดีมากฉันได้รับการปรับปรุงโดยคำตอบด้วยความคิดเห็นที่
Andy Hayden

1
ฉันรู้สึกประหลาดใจที่ได้เรียนรู้ในวันนี้ว่าเลิกใช้แล้ว! จากความคิดเห็นบางส่วนในเมตาโพสต์นี้: meta.stackoverflow.com/questions/297404/… ฉันตัดสินใจที่จะเพิ่มคำตอบใหม่แทนที่จะพยายามแก้ไขให้คุณ
Kyle Heuton

2
@Snoozer ใช่ฉันไม่คิดว่าการจัดเรียงที่เคยหนีหายไปไหน (ส่วนใหญ่เป็นมันใช้อย่างกว้างขวางในหนังสือ Wes') แต่ได้มีการเปลี่ยนแปลงบางอย่างที่ยิ่งใหญ่ในการเรียกร้องการจัดเรียง ขอบคุณ! .. ฉันต้องการให้แพนด้าผ่านพันล้านคำตอบโดยอัตโนมัติสำหรับการคัดค้าน!
Andy Hayden

40

ตั้งแต่ pandas 0.17.0 DataFrame.sort()เลิกใช้แล้วและถูกตั้งค่าให้ลบใน pandas เวอร์ชันอนาคต วิธีการเรียงลำดับดาต้าเฟรมตามค่าปัจจุบันคือDataFrame.sort_values

ดังนั้นคำตอบสำหรับคำถามของคุณก็จะเป็นเช่นนี้

df.sort_values(['b', 'c'], ascending=[True, False], inplace=True)

4

สำหรับ dataframes ขนาดใหญ่ของข้อมูลตัวเลขคุณอาจเห็นการปรับปรุงประสิทธิภาพที่สำคัญผ่านnumpy.lexsortซึ่งทำการเรียงลำดับทางอ้อมโดยใช้ลำดับของคีย์:

import pandas as pd
import numpy as np

np.random.seed(0)

df1 = pd.DataFrame(np.random.randint(1, 5, (10,2)), columns=['a','b'])
df1 = pd.concat([df1]*100000)

def pdsort(df1):
    return df1.sort_values(['a', 'b'], ascending=[True, False])

def lex(df1):
    arr = df1.values
    return pd.DataFrame(arr[np.lexsort((-arr[:, 1], arr[:, 0]))])

assert (pdsort(df1).values == lex(df1).values).all()

%timeit pdsort(df1)  # 193 ms per loop
%timeit lex(df1)     # 143 ms per loop

สิ่งหนึ่งที่แปลกประหลาดคือลำดับการเรียงที่กำหนดด้วยnumpy.lexsortถูกกลับรายการ(-'b', 'a')เรียงลำดับตามลำดับaแรก เราคัดค้านซีรี่ส์bเพื่อแสดงว่าเราต้องการซีรีส์นี้จากมากไปหาน้อย

โปรดทราบว่าnp.lexsortเรียงลำดับตามค่าตัวเลขเท่านั้นในขณะที่pd.DataFrame.sort_valuesทำงานกับสตริงหรือค่าตัวเลข ใช้กับสตริงจะให้:np.lexsortTypeError: bad operand type for unary -: 'str'

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.