2012-12-12 24 views
32

में कस्टम सॉर्टिंग मेरे पास पाइथन पांडा डेटाफ्रेम है, जिसमें एक कॉलम में महीना नाम होता है।पांडा डेटाफ्रेम

मैं कैसे उदाहरण के लिए तरह एक शब्दकोश का उपयोग कर एक कस्टम कर सकते हैं,:

custom_dict = {'March':0, 'April':1, 'Dec':3} 
+1

क्या कॉलम में महीने का नाम होता है इसका मतलब है कि एक कॉलम है जिसमें महीने के नाम (मेरे उत्तर के रूप में), या कॉलम नाम वाले कई कॉलम महीने के नाम के रूप में (eumiro के रूप में) हैं? –

उत्तर

48

पांडा 0.15 Categorical Series शुरू की है, जो एक की अनुमति देता है ऐसा करने के लिए बहुत स्पष्ट तरीका:

पहले महीने कॉलम को एक स्पष्ट बनाएं और उपयोग करने के लिए ऑर्डर निर्दिष्ट करें।

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 

अब, जब आप महीने के स्तंभ को क्रमबद्ध यह है कि सूची के संबंध में सॉर्ट देगा:

In [23]: df.sort("m") 
Out[23]: 
    a b  m 
0 1 2 March 
2 3 4 April 
1 5 6 Dec 

नोट: यदि एक मूल्य सूची यह NaN में परिवर्तित हो जाएगा में नहीं है।


रुचि रखने वालों के लिए एक पुराना जवाब ...

आप बिचौलिये श्रृंखला बना सकते हैं, और set_index उस पर:

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 

के रूप में नए पांडा में टिप्पणी की,, श्रृंखला में replace विधि अधिक सुंदर तरीके से करने के लिए है:

s = df['m'].replace({'March':0, 'April':1, 'Dec':3}) 

मामूली अंतर यह है कि यदि शब्दकोश के बाहर कोई मूल्य नहीं है तो यह नहीं बढ़ेगा (यह वही रहेगा)।

+0

's = df ['m']। प्रतिस्थापित करें ({'मार्च': 0, 'अप्रैल': 1, 'दिसंबर': 3}) 'लाइन 2 के लिए भी काम करता है - केवल पांडा सीखने वाले किसी के लिए मेरे जैसे – kdauria

+0

@kdauria अच्छी जगह! (कुछ समय बाद मैंने यह लिखा था!) ​​निश्चित रूप से सर्वोत्तम विकल्प को प्रतिस्थापित करें, दूसरा '.apply ({' मार्च ': 0,' अप्रैल ': 1,' Dec ': 3} .get) का उपयोग करना है। ':) 0.15 में हमारे पास स्पष्ट श्रृंखला/कॉलम होंगे, इसलिए इसका सबसे अच्छा तरीका उपयोग करना होगा और फिर सॉर्ट बस काम करेगा। –

+0

@ एंडीहेडन मैंने दूसरी पंक्ति को 'प्रतिस्थापन' विधि के साथ बदलने की स्वतंत्रता ली है। मुझे उम्मीद है कि ठीक है। –

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

साथ कॉलम मार्च, अप्रैल एक DataFrame रिटर्न, दिसम्बर

+0

यह किसी भी मौजूदा कोड में शेव लिखने के लिए काम करता है और आसान है। धन्यवाद! – posdef

8

खेल के लिए थोड़ा देर हो चुकी है, लेकिन यहां एक ऐसा फ़ंक्शन बनाने का एक तरीका है जो पैंडस श्रृंखला, डेटाफ्रेम, और बहुविशिष्ट डेटाफ्रेम ऑब्जेक्ट्स को मनमानी कार्यों का उपयोग कर बनाता है।

मैं df.iloc[index] विधि का उपयोग करता हूं, जो किसी श्रृंखला/डेटाफ्रेम में स्थिति के अनुसार एक पंक्ति का संदर्भ देता है (df.loc की तुलना में, जो मान के संदर्भ में)।

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 

आप इस का उपयोग कस्टम छँटाई कार्यों बनाने के लिए कर सकते हैं: इस का उपयोग करना, हम सिर्फ एक समारोह है कि स्थितीय तर्क की एक श्रृंखला रिटर्न करना होगा।

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 

यह भी multiindex DataFrames और सीरीज वस्तुओं पर काम करता है:: इस dataframe एंडी हेडन के जवाब में इस्तेमाल पर काम करता है

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 

मेरे लिए यह साफ लगता है, लेकिन यह भरोसा करने की बजाय भारी अजगर संचालन का उपयोग करता है बल्कि अनुकूलित पांडा संचालन पर। मैंने कोई तनाव परीक्षण नहीं किया है, लेकिन मुझे लगता है कि यह बहुत बड़े डेटाफ्रेम पर धीमा हो सकता है। सुनिश्चित नहीं है कि प्रदर्शन कैसे कॉलम को जोड़ने, सॉर्ट करने, फिर हटाने की तुलना करता है। कोड को तेज करने पर कोई सुझाव की सराहना की जाएगी!

+0

क्या यह एकाधिक कॉलम/इंडेक्स को सॉर्ट करने के लिए काम करेगा? – ConanG

+0

हां, लेकिन चयनित उत्तर यह करने का एक बेहतर तरीका है। यदि आपके पास एकाधिक इंडेक्स हैं, तो बस उन्हें अपने इच्छित क्रम के अनुसार व्यवस्थित करें, फिर सभी इंडेक्स स्तरों को सॉर्ट करने के लिए 'df.sort_index()' का उपयोग करें। – delgadom

संबंधित मुद्दे