2016-04-09 4 views
6

मैं विशिष्ट रूप से pd.get_dummies() का उपयोग करके, मूलभूत चर को बाइनरी मैट्रिक्स में परिवर्तित करके मशीन लर्निंग वर्गीकरण कार्य के लिए डेटा प्रीप्रोसेसिंग कर रहा हूं। यह एक पांडस डेटाफ्रेम कॉलम पर लागू होता है और मूल कॉलम में विशिष्ट चर की अनूठी संख्या की मूल और चौड़ाई के रूप में पंक्तियों की एक ही संख्या के साथ एक नया डेटाफ्रेम आउटपुट करता है।पायथन पांडा: कॉलम असाइनमेंट के लिए पांडों की तुलना में इतना तेज क्यों है? क्या मैं आगे अनुकूलित कर सकता हूं?

मुझे इसे आकार के डेटाफ्रेम के लिए पूरा करने की आवश्यकता है: (3,000,000 x 16) जो आकार के बाइनरी मैट्रिक्स को आउटपुट करता है: (3,000,000 x 600)

प्रक्रिया के दौरान, बाइनरी मैट्रिक्स pd.get_dummies() में कनवर्ट करने का चरण बहुत तेज़ है, लेकिन आउटपुट मैट्रिक्स को असाइनमेंट pd.DataFrame.loc[] का उपयोग करके बहुत धीमा था। चूंकि मैंने सीधे np.ndarray पर सहेजने के लिए स्विच किया है जो अधिक तेज है, मुझे आश्चर्य है कि क्यों? (कृपया समय तुलना के लिए प्रश्न के नीचे टर्मिनल आउटपुट देखें)

n.b. टिप्पणियों में बताया गया है, मैं बस पूरे फ्रेम पर सभी pd.get_dummies() कर सकता था। हालांकि, कुछ कॉलमों को अनुरूप प्रीप्रोकैसिंग की आवश्यकता होती है, यानी: बाल्टी में डालना। संभालने का सबसे कठिन कॉलम एक कॉलम है जिसमें टैग की एक स्ट्रिंग होती है (, या , से अलग, जिसे इस तरह संसाधित किया जाना चाहिए: df[col].str.replace(' ','').str.get_dummies(sep=',')। इसके अलावा, प्रीप्रोसेस्ड ट्रेनिंग सेट और टेस्ट सेट को कॉलम के समान सेट की आवश्यकता होती है (all_cols से विरासत में) । के रूप में वे वर्तमान में एक ही सुविधाओं एक बार वे एक मैट्रिक्स में टूट रहे हैं नहीं हो सकता

कृपया प्रत्येक संस्करण के लिए नीचे दिए गए कोड को देखने के

DataFrame संस्करण:

def preprocess_df(df): 
    with open(PICKLE_PATH + 'cols.pkl', 'rb') as handle: 
     cols = pickle.load(handle) 

    x = np.zeros(shape=(len(df),len(cols))) 
    # x = pd.DataFrame(columns=all_cols) 

    for col in df.columns: 
     # 1. make binary matrix 
     df_col = pd.get_dummies(df[col], prefix=str(col)) 

     print "Processed: ", col, datetime.datetime.now() 

     # 2. assign each value in binary matrix to col in output 
     for dummy_col in df_col.columns: 
      x.loc[:, dummy_col] = df_col[dummy_col] 

     print "Assigned: ", col, datetime.datetime.now() 

    return x.values 

एनपी संस्करण :

def preprocess_np(df): 
    with open(PICKLE_PATH + 'cols.pkl', 'rb') as handle: 
     cols = pickle.load(handle) 

    x = np.zeros(shape=(len(df),len(cols))) 

    for col in df.columns: 
     # 1. make binary matrix 
     df_col = pd.get_dummies(df[col], prefix=str(col)) 

     print "Processed: ", col, datetime.datetime.now() 

     # 2. assign each value in binary matrix to col in output 
     for dummy_col in df_col.columns: 
      idx = [i for i,j in enumerate(all_cols) if j == dummy_col][0] 
      x[:, idx] = df_col[dummy_col].values.T 

     print "Assigned: ", col, datetime.datetime.now() 

    return x 

समयबद्ध आउटपुट (10,000 उदाहरण)

DataFrame संस्करण:

Processed: Weekday 
Assigned: Weekday 0.437081 
Processed: Hour 0.002366 
Assigned: Hour 1.33815 

एनपी संस्करण:

Processed: Weekday 
Assigned: Weekday 0.006992 
Processed: Hour 0.002632 
Assigned: Hour 0.008989 

वहाँ एक अलग दृष्टिकोण आगे इस अनुकूलन करने के लिए है? मुझे इस समय दिलचस्पी है कि मैं संभावित रूप से उपयोगी सुविधा को छोड़ रहा हूं क्योंकि आउटपुट में अतिरिक्त 15,000 कॉलम को संसाधित करना बहुत धीमा है।

मेरे द्वारा उठाए जा रहे दृष्टिकोण पर कोई सामान्य सलाह भी सराहना की जाती है!

धन्यवाद

+0

क्या आप पूरे डेटा.frame पर get_dummies का उपयोग नहीं कर सकते? आप इसे प्रति कॉलम क्यों लागू कर रहे हैं? – Zelazny7

+0

आह! दिलचस्प सवाल, कुछ कॉलमों को अनुरूप प्रीप्रोकैसिंग की आवश्यकता होती है, यानी: बाल्टी में डालना।इसके अलावा, एक विशेष कॉलम टैग की सूचियों को संभालता है, जिसे इस तरह संसाधित किया जाना चाहिए: 'df [col] .str.replace ('', '')। Str.get_dummies (sep = ',')'। साथ ही, प्रीप्रोसेस्ड ट्रेनिंग सेट और टेस्ट सेट को कॉलम के एक ही सेट की आवश्यकता होती है ('all_cols' से विरासत में मिली) क्योंकि उनके पास मैट्रिक्स में टूटा जाने के बाद समान सुविधाएं मौजूद नहीं हो सकती हैं। – jfive

+1

@jfive आम तौर पर इन्हें टाइमडेल्टस के रूप में आउटपुट करना सबसे अच्छा है, है ना? तो यह और अधिक स्पष्ट है कि क्या हो रहा है। बस बाद की तारीखों से बाद की तिथियों को घटाएं, या टाइमर के रूप में 'टाइमिट आयात डिफ़ॉल्ट_टिमर से' और उस टाइमर का उपयोग करके। – Paul

उत्तर

1

एक प्रयोग x.loc[:, dummy_col] = df_col[dummy_col].values के साथ बदल जाएगा। यदि इनपुट एक श्रृंखला है, तो पांडा प्रत्येक असाइनमेंट के लिए सूचकांक के क्रम की जांच कर रहा है। एक अंडारे के साथ असाइन करना अगर यह अनावश्यक है तो उसे बंद कर देगा, और इसे प्रदर्शन में सुधार करना चाहिए।

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

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