2016-08-29 6 views
6

मेरे पास डेटाफ्रेम है जहां मैं 'ऑब्जेक्ट' से 'श्रेणी' के कई कॉलम बदलना चाहता हूं।एकाधिक पांडस डीएफ कॉलम को लूप के बिना वर्गीकृत करने के लिए कैसे बदलें

मैं नाव के लिए एक ही समय में कई स्तंभ को बदल सकते हैं,

dftest[['col3', 'col4', 'col5', 'col6']] = \ 
    dftest[['col3', 'col4', 'col5', 'col6']].astype(float) 

'श्रेणी' मैं यह एक ही मैं एक के बाद एक करने की ज़रूरत नहीं कर सकते, के लिए (या here की तरह एक पाश में) ।

for col in ['col1', 'col2']: 
    dftest[col] = dftest[col].astype('category') 

प्रश्न: वहाँ बदलाव के लिए सभी 'नाव' उदाहरण में एक बार की तरह में कॉलम चाहता था ऐसा करने का कोई तरीका है?

अगर मैं एक ही समय में कई स्तंभ करने की कोशिश मेरे पास है:

dftest[['col1','col2']] = dftest[['col1','col2']].astype('category') 
## NotImplementedError: > 1 ndim Categorical are not supported at this time 

मेरे वर्तमान कार्यशील परीक्षण कोड:

import numpy as np 
import pandas as pd 

factors= np.array([ 
     ['a', 'xx'], 
     ['a', 'xx'], 
     ['ab', 'xx'], 
     ['ab', 'xx'], 
     ['ab', 'yy'], 
     ['cc', 'yy'], 
     ['cc', 'zz'], 
     ['d', 'zz'], 
     ['d', 'zz'], 
     ['g', 'zz'] 
     ]) 

values = np.random.randn(10,4).round(2) 

dftest = pd.DataFrame(np.hstack([factors,values]), 
        columns = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6']) 

#dftest[['col1','col2']] = dftest[['col1','col2']].astype('category') 
## NotImplementedError: > 1 ndim Categorical are not supported at this time 

## it works with individual astype 
#dftest['col2'] = dftest['col2'].astype('category') 
#dftest['col1'] = dftest['col1'].astype('category') 

print(dftest) 

## doing a loop 
for col in ['col1', 'col2']: 
    dftest[col] = dftest[col].astype('category') 


dftest[['col3', 'col4', 'col5', 'col6']] = \ 
    dftest[['col3', 'col4', 'col5', 'col6']].astype(float) 

dftest.dtypes 

उत्पादन:

col1 category 
col2 category 
col3  float64 
col4  float64 
col5  float64 
col6  float64 
dtype: object 

== [अपडेट] ==

मुझे अब लूप का उपयोग करने में कोई समस्या नहीं है, जिसे मैं चाल जानता हूं, लेकिन मैंने सवाल पूछा क्योंकि मैं सीखना/समझना चाहता था कि मुझे 'श्रेणी' के लिए लूप करने की ज़रूरत क्यों है और फ्लोट के लिए नहीं, अगर वहां ऐसा करने का कोई और तरीका नहीं है।

+3

जिज्ञासा से बाहर, बिंदु क्या है? स्पीड? – IanS

+0

@IanS मेरा अपडेट देखें –

+1

"लागू नहीं किया गया" आम तौर पर इसका अर्थ है कि यह भविष्य के संस्करण के लिए योजनाबद्ध है। वर्गीकृत अपेक्षाकृत नए हैं इसलिए हम भविष्य में 1 से अधिक कॉलम के लिए काम करने के लिए '.astype (' श्रेणी) 'की अपेक्षा कर सकते हैं। – ayhan

उत्तर

2

यह तुरंत स्पष्ट नहीं है के तहत पाशन का उपयोग करता है क्या dftest[['col1','col2']].astype('category') का परिणाम होना चाहिए, यानी परिणामस्वरूप कॉलम को समान श्रेणियां साझा करनी चाहिए या नहीं।

कॉलम पर लूपिंग प्रत्येक कॉलम में श्रेणियों का एक अलग सेट होता है। (मेरा मानना ​​है कि यह आपके उदाहरण में एक वांछित परिणाम है।)

दूसरी ओर, .astype(float) अलग तरह से काम करता है: यह एक 1d सरणी के लिए अंतर्निहित मूल्यों Ravels, तैरता के लिए डाले, और फिर इसे मूल आकार में वापस नयी आकृति प्रदान । इस तरह यह कॉलम पर बस फिर से शुरू करने से तेज हो सकता है। आप उच्च स्तर कार्यों के साथ category के लिए इस व्यवहार का अनुकरण कर सकते हैं:

result = dftest[['col1', 'col2']].stack().astype('category').unstack() 

लेकिन तब आप दोनों स्तंभ द्वारा साझा श्रेणियों का एक सेट प्राप्त करें:

result['col1'] 
Out[36]: 
0  a 
1  a 
2 ab 
3 ab 
4 ab 
5 cc 
6 cc 
7  d 
8  d 
9  g 
Name: col1, dtype: category 
Categories (8, object): [a < ab < cc < d < g < xx < yy < zz] 
+0

धन्यवाद @ptrj, अब मुझे लगता है कि समस्या किसी अन्य प्रकार का कास्टिंग नहीं है, लेकिन स्पष्ट कॉलम के मामले में स्तरों को कैसे संभालना है। मैंने उस पर नहीं सोचा, लेकिन अब मुझे सही समझ में आता है। ज्ञान के लिए धन्यवाद। –

1

आप इसे इस तरह से कर सकते हैं:

In [99]: pd.concat([dftest[['col1', 'col2']].apply(lambda x: x.astype('category')), dftest.ix[:, 'col3':].astype('float')], axis=1) 
Out[99]: 
    col1 col2 col3 col4 col5 col6 
0 a xx 0.30 2.28 0.84 0.31 
1 a xx -0.13 2.04 2.62 0.49 
2 ab xx -0.34 -0.32 -1.87 1.49 
3 ab xx -1.18 -0.57 -0.57 0.87 
4 ab yy 0.66 0.65 0.96 0.07 
5 cc yy 0.88 2.43 0.76 1.93 
6 cc zz 1.81 -1.40 -2.29 -0.13 
7 d zz -0.05 0.60 -0.78 -0.28 
8 d zz -0.36 0.98 0.23 -0.17 
9 g zz -1.31 -0.84 0.02 0.47 

In [100]: pd.concat([dftest[['col1', 'col2']].apply(lambda x: x.astype('category')), dftest.ix[:, 'col3':].astype('float')], axis=1).dtypes 
Out[100]: 
col1 category 
col2 category 
col3  float64 
col4  float64 
col5  float64 
col6  float64 
dtype: object 

लेकिन यह नहीं होगा बहुत तेज, apply() के रूप में विधि हुड

+0

धन्यवाद @ मैक्सयू, लेकिन सवाल का उद्देश्य "फ्लोट में जैसे कई स्तंभों के लिए मैं श्रेणी में क्यों नहीं बदल सकता?"। मैं जानना चाहता था कि यह मेरे पांडा knlowledge की एक सीमा थी।अद्यतन –

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