Tôi có khung dữ liệu pandas python, trong đó cột chứa tên tháng.Sắp xếp tùy chỉnh trong khung dữ liệu gấu trúc
Làm thế nào tôi có thể làm một tùy chỉnh loại sử dụng một cuốn từ điển, ví dụ:
custom_dict = {'March':0, 'April':1, 'Dec':3}
Tôi có khung dữ liệu pandas python, trong đó cột chứa tên tháng.Sắp xếp tùy chỉnh trong khung dữ liệu gấu trúc
Làm thế nào tôi có thể làm một tùy chỉnh loại sử dụng một cuốn từ điển, ví dụ:
custom_dict = {'March':0, 'April':1, 'Dec':3}
Pandas 0,15 giới thiệu Categorical Series, cho phép một cách rõ ràng hơn để thực hiện việc này:
Đầu tiên, hãy tạo cột tháng một cách phân loại và chỉ định thứ tự sử dụng.
In [21]: df['m'] = pd.Categorical(df['m'], ["March", "April", "Dec"])
In [22]: df # looks the same!
Out[22]:
a b m
0 1 2 March
1 5 6 Dec
2 3 4 April
Bây giờ, khi bạn sắp xếp các cột tháng nó sẽ sắp xếp liên quan đến danh sách đó với:
In [23]: df.sort("m")
Out[23]:
a b m
0 1 2 March
2 3 4 April
1 5 6 Dec
Lưu ý: nếu một giá trị không nằm trong danh sách này sẽ được chuyển đổi sang NaN.
Một câu trả lời cũ cho những người quan tâm ...
Bạn có thể tạo một loạt trung gian, và set_index
trên rằng:
df = pd.DataFrame([[1, 2, 'March'],[5, 6, 'Dec'],[3, 4, 'April']], columns=['a','b','m'])
s = df['m'].apply(lambda x: {'March':0, 'April':1, 'Dec':3}[x])
s.sort()
In [4]: df.set_index(s.index).sort()
Out[4]:
a b m
0 1 2 March
1 3 4 April
2 5 6 Dec
Như nhận xét, trong gấu trúc mới, Series có phương thức replace
để làm điều này một cách trang nhã hơn:
s = df['m'].replace({'March':0, 'April':1, 'Dec':3})
Sự khác biệt nhỏ là điều này sẽ không tăng nếu có giá trị ngoài từ điển (nó sẽ chỉ giữ nguyên).
's = df ['m']. Thay thế ({'March': 0, 'April': 1, 'Dec': 3})' hoạt động cho dòng 2 - chỉ vì lợi ích của bất kỳ ai học gấu trúc giống như tôi – kdauria
@ kdauria vị trí tốt! (đã được một thời gian kể từ khi tôi đã viết này!) Thay thế chắc chắn lựa chọn tốt nhất, khác là sử dụng '.apply ({'March': 0, 'April': 1, 'Dec': 3} .get)' :) Trong 0.15 chúng ta sẽ có Categorical Series/columns, vì vậy cách tốt nhất là sử dụng nó và sau đó sắp xếp sẽ hoạt động. –
@AndyHayden Tôi đã tự do thay thế dòng thứ hai bằng phương pháp 'thay thế'. Tôi hy vọng đó là Ok. –
import pandas as pd
custom_dict = {'March':0,'April':1,'Dec':3}
df = pd.DataFrame(...) # with columns April, March, Dec (probably alphabetically)
df = pd.DataFrame(df, columns=sorted(custom_dict, key=custom_dict.get))
trả về một DataFrame với các cột Tháng Ba, Tháng Tư, Tháng Mười Hai
Công việc này và dễ dàng hơn để viết shove trong bất kỳ mã hiện có. Cảm ơn bạn! – posdef
Một chút muộn cho trò chơi, nhưng đây là cách để tạo chức năng sắp xếp các chuỗi đối tượng DataFrame, DataFrame và multiindex DataFrame sử dụng các chức năng tùy ý.
Tôi sử dụng phương thức df.iloc[index]
, tham chiếu một hàng trong một Series/DataFrame theo vị trí (so với df.loc
, tham chiếu theo giá trị). Sử dụng điều này, chúng tôi chỉ cần có một hàm trả về một loạt các đối số vị trí:
def sort_pd(key=None,reverse=False,cmp=None):
def sorter(series):
series_list = list(series)
return [series_list.index(i)
for i in sorted(series_list,key=key,reverse=reverse,cmp=cmp)]
return sorter
Bạn có thể sử dụng tính năng này để tạo các chức năng sắp xếp tùy chỉnh. Này hoạt động trên các dataframe sử dụng trong câu trả lời Andy Hayden:
df = pd.DataFrame([
[1, 2, 'March'],
[5, 6, 'Dec'],
[3, 4, 'April']],
columns=['a','b','m'])
custom_dict = {'March':0, 'April':1, 'Dec':3}
sort_by_custom_dict = sort_pd(key=custom_dict.get)
In [6]: df.iloc[sort_by_custom_dict(df['m'])]
Out[6]:
a b m
0 1 2 March
2 3 4 April
1 5 6 Dec
này cũng hoạt động trên DataFrames multiindex và các đối tượng Series:
months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
df = pd.DataFrame([
['New York','Mar',12714],
['New York','Apr',89238],
['Atlanta','Jan',8161],
['Atlanta','Sep',5885],
],columns=['location','month','sales']).set_index(['location','month'])
sort_by_month = sort_pd(key=months.index)
In [10]: df.iloc[sort_by_month(df.index.get_level_values('month'))]
Out[10]:
sales
location month
Atlanta Jan 8161
New York Mar 12714
Apr 89238
Atlanta Sep 5885
sort_by_last_digit = sort_pd(key=lambda x: x%10)
In [12]: pd.Series(list(df['sales'])).iloc[sort_by_last_digit(df['sales'])]
Out[12]:
2 8161
0 12714
3 5885
1 89238
Đối với tôi đây cảm thấy sạch sẽ, nhưng nó sử dụng hoạt động trăn nặng nề hơn là dựa về các hoạt động gấu trúc được tối ưu hóa. Tôi đã không thực hiện bất kỳ thử nghiệm căng thẳng nhưng tôi tưởng tượng điều này có thể làm chậm trên DataFrames rất lớn. Không chắc chắn hiệu suất so sánh với việc thêm, sắp xếp, sau đó xóa cột. Bất kỳ lời khuyên nào về tăng tốc mã sẽ được đánh giá cao!
Điều này có hoạt động để sắp xếp nhiều cột/chỉ mục không? – ConanG
có, nhưng câu trả lời đã chọn là cách tốt hơn nhiều để thực hiện việc này. Nếu bạn có nhiều chỉ mục, chỉ cần sắp xếp chúng theo thứ tự sắp xếp bạn thích, sau đó sử dụng 'df.sort_index()' để sắp xếp tất cả các mức chỉ mục. – delgadom
Một cột có chứa tên tháng có nghĩa là có cột chứa tên tháng (như câu trả lời của tôi) hoặc nhiều cột có tên cột làm tên tháng (như tên của eumiro)? –