2013-07-12 34 views
44

Tôi có khung sau dữ liệu:Làm thế nào để sắp xếp khung dữ liệu gấu trúc bằng cách sử dụng các giá trị từ một số cột?

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

Hoặc, ở dạng có thể đọc được con người:

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

Sau đây công trình sắp xếp-lệnh như mong đợi:

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

Output:

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

Nhưng lệnh sau:

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

kết quả trong

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

và đây không phải là những gì tôi mong đợi. Tôi hy vọng có các giá trị trong cột đầu tiên được sắp xếp từ lớn nhất đến nhỏ nhất, và nếu có giá trị giống nhau trong cột đầu tiên, theo thứ tự các giá trị tăng dần từ cột thứ hai.

Có ai biết tại sao nó không hoạt động như mong đợi không?

THÊM

Đây là copy-paste:

>>> 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

Bạn đang sử dụng phiên bản gấu trúc và vón cục nào? –

Trả lời

42

Mã của bạn làm việc cho tôi.

>>> 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 

Bạn có dán như là?

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

CẬP NHẬTDataFrame.sort bị phản đối; sử dụng 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

Gợi ý: thứ tự đảo ngược với bản gốc ở dưới cùng, cập nhật lên trên cùng. Đọc trên xuống Tôi đã thử khối đầu tiên và tự hỏi tại sao nó thất bại, bị nhầm lẫn gấp đôi bởi "nó làm việc cho tôi" và "bạn đã dán như là" (chắc chắn đó là lỗi của tôi!). Sau đó, tôi cuộn và thấy bản cập nhật ... – Hendy

2

Nếu bạn đang viết mã này như một tập tin kịch bản sau đó bạn sẽ phải viết nó như thế này:

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

Sử dụng sort có thể dẫn đến thông điệp cảnh báo. Xem thảo luận github. Vì vậy, bạn có thể muốn sử dụng sort_values, tài liệu here

Sau đó, mã của bạn có thể trông như thế này:

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

Tôi nhận được cảnh báo khác '/Applications/anaconda/lib/python2.7/site-packages/spyderlib/widgets/externalshell/start_ipython_kernel.py:1: FutureWarning: sắp xếp (cột = ....) không được chấp nhận, sử dụng sort_values ​​(by = .....) ' – abhiieor

+0

@patapouf_ai Không,' sắp xếp' hiện không được chấp nhận – oulenz

1

Tôi đã tìm thấy điều này là thực sự hữu ích:

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'])) 

Lưu ý rằng không giống như tiêu chuẩn columns=,ascending= đối số, tại đây tên cột và thứ tự sắp xếp của chúng ở cùng một vị trí. Kết quả là mã của bạn dễ đọc và bảo trì hơn rất nhiều.

Lưu ý các cuộc gọi thực tế để .sort là không thay đổi, skw (s ort kw args) chỉ là một chức năng helper nhỏ mà phân tích các cột và trả về thông thường columns=ascending= thông số cho bạn. Vượt qua nó bất kỳ loại kwargs khác như bạn thường làm. Sao chép/dán mã sau vào ví dụ: địa phương của bạn utils.py sau đó quên nó và chỉ sử dụng nó như trên.

# 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

Điều này có vẻ như quá mức cần thiết, so với các tùy chọn khác. – digitaldavenyc

+0

chỉ xem ví dụ, không phải là hàm 'sortkwargs'. đó là định nghĩa một lần mà bạn có thể lưu trữ và nhập từ ví dụ của bạn 'util.py'. mã của bạn sẽ linh hoạt hơn và dễ đọc hơn so với cú pháp 'sort' mặc định. – miraculixx

+0

bỏ phiếu xuống tất cả những gì bạn thích, vui lòng thêm nhận xét để tôi có thể cải thiện câu trả lời – miraculixx

7

Phương thức dataframe.sort() là - vì vậy sự hiểu biết của tôi - không được chấp nhận trong gấu trúc> 0,18. Để giải quyết vấn đề của bạn, bạn nên sử dụng dataframe.sort_values ​​() thay vì:

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

Kết quả trông như thế này:

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

Trong trường hợp của tôi, câu trả lời được chấp nhận không làm việc:

f.sort_values ​​(by = [ "c1", "c2"], tăng dần = [False, True])

Chỉ có làm việc sau đây như mong đợi:

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

Nghiêm túc? Có một thứ gọi là [inplace] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sort.html) trong Pandas bạn biết – Hng

Các vấn đề liên quan