2013-10-03 8 views
5
में एकाधिक स्तंभों पर numpy सरणी छंटाई

मैं स्तम्भ 1 पर निम्नलिखित सरणी सॉर्ट करने के लिए कोशिश कर रहा हूँ, तो COLUMN2 और फिर स्तम्भ 3अजगर

[['2008' '1' '23' 'AAPL' 'Buy' '100'] 
['2008' '1' '30' 'AAPL' 'Sell' '100'] 
['2008' '1' '23' 'GOOG' 'Buy' '100'] 
['2008' '1' '30' 'GOOG' 'Sell' '100'] 
['2008' '9' '8' 'GOOG' 'Buy' '100'] 
['2008' '9' '15' 'GOOG' 'Sell' '100'] 
['2008' '5' '1' 'XOM' 'Buy' '100'] 
['2008' '5' '8' 'XOM' 'Sell' '100']] 

मैं निम्नलिखित कोड का इस्तेमाल किया:

idx=np.lexsort((order_array[:,2],order_array[:,1],order_array[:,0])) 
    order_array=order_array[idx] 

परिणामी सरणी

[['2008' '1' '23' 'AAPL' 'Buy' '100'] 
['2008' '1' '23' 'GOOG' 'Buy' '100'] 
['2008' '1' '30' 'AAPL' 'Sell' '100'] 
['2008' '1' '30' 'GOOG' 'Sell' '100'] 
['2008' '5' '1' 'XOM' 'Buy' '100'] 
['2008' '5' '8' 'XOM' 'Sell' '100'] 
['2008' '9' '15' 'GOOG' 'Sell' '100'] 
['2008' '9' '8' 'GOOG' 'Buy' '100']] 

समस्या यह है कि अंतिम दो पंक्तियां गलत हैं। सही सरणी में अंतिम पंक्ति के रूप में अंतिम पंक्ति होनी चाहिए। मैंने सब कुछ करने की कोशिश की है लेकिन यह समझ में नहीं आता कि यह क्यों हो रहा है। कुछ मदद की सराहना करेंगे।

मैं order_array प्राप्त करने के लिए निम्न कोड का उपयोग कर रहा हूं।

for i in …. 
    x= ldt_timestamps[i] # this is a list of timestamps 
    s_sym=…… 
    list=[int(x.year),int(x.month),int(x.day),s_sym,'Buy',100] 
    rows_list.append(list) 

order_array=np.array(rows_list) 
+0

की ([कई कुल्हाड़ियों करके 2D numpy सरणी छंटाई] संभव डुप्लिकेट http://stackoverflow.com/questions/2706605/sorting-a-2d-numpy-array-by-multiple -एक्सिस) उस उत्तर का प्रयोग करें, लेकिन एक प्रकार का उपयोग करें जो आपके डेटा (सभी तारों) के लिए समझ में आता है, उदाहरण के लिए 'डीटी = डीटी = [('वाई', एनपी.यूंट 32), ('एम', एनपी.यूंट 32), ('डी', एनपी.यूंट 32), ('सीएम', 'एस 4'), ('बीएस' , 'एस 4'), ('हुह', एनपी.यूंट 32)] ' – askewchan

उत्तर

7

tldr: संख्यात्मक सरणी पर संख्यात्मक गणना करते समय NumPy चमकता है। हालांकि यह संभव है (नीचे देखें) NumPy इसके लिए उपयुक्त नहीं है। आप शायद पांडों का उपयोग बंद कर रहे हैं।


समस्या का कारण:

मानों को स्ट्रिंग्स के रूप में हल कर किया जा रहा है । आपको उन्हें ints के रूप में सॉर्ट करने की आवश्यकता है।

In [7]: sorted(['15', '8']) 
Out[7]: ['15', '8'] 

In [8]: sorted([15, 8]) 
Out[8]: [8, 15] 

ऐसा इसलिए हुआ क्योंकि order_array तार शामिल हैं। आपको उन तारों को ints पर उचित रूप से परिवर्तित करने की आवश्यकता है।

स्ट्रिंग-डाइप से संख्यात्मक डाइप के लिए dtypes कनवर्ट करने के लिए एक नई सरणी के लिए स्थान आवंटित करने की आवश्यकता होती है। इसलिए, आप शुरुआत से order_array बनाने के तरीके को संशोधित करने से बेहतर होंगे।

दिलचस्प है, भले ही आप ints के लिए मान परिवर्तित, जब आप डिफ़ॉल्ट रूप से

order_array = np.array(rows_list) 

NumPy फोन एक समरूप सरणी पैदा करता है। एक सजातीय सरणी में प्रत्येक मूल्य में एक ही प्रकार का होता है। तो NumPy ने आपके सभी मानों के बीच सामान्य संप्रदाय को खोजने का प्रयास किया और तारों को बदलने के प्रयासों को विफल करने के प्रयास को विफल कर दिया, जिससे स्ट्रिंग डाइट टाइप किया गया!

आप अपने लिए dtype जांच कर सकते हैं order_array.dtype निरीक्षण: अब

In [42]: order_array = np.array(rows_list) 

In [43]: order_array.dtype 
Out[43]: dtype('|S4') 

, हम इसे ठीक कर सकता हूँ?


एक वस्तु dtype का उपयोग करना:

सबसे आसान तरीका है एक 'वस्तु' का उपयोग करने के लिए है dtype

In [53]: order_array = np.array(rows_list, dtype='object') 

In [54]: order_array 
Out[54]: 
array([[2008, 1, 23, AAPL, Buy, 100], 
     [2008, 1, 30, AAPL, Sell, 100], 
     [2008, 1, 23, GOOG, Buy, 100], 
     [2008, 1, 30, GOOG, Sell, 100], 
     [2008, 9, 8, GOOG, Buy, 100], 
     [2008, 9, 15, GOOG, Sell, 100], 
     [2008, 5, 1, XOM, Buy, 100], 
     [2008, 5, 8, XOM, Sell, 100]], dtype=object) 

समस्या है कि यहाँ np.lexsort या np.sort की सरणियों पर काम नहीं करते है dtype object। कि समस्या को हल करने के लिए, आप क्रमबद्ध सकता rows_list बनाने से पहले order_list:

import operator 
import datetime as DT 

for i in ...: 
    seq = [DT.date(int(x.year), int(x.month), int(x.day)) ,s_sym, 'Buy', 100] 
    rows_list.append(seq) 
rows_list.sort(key=operator.itemgetter(0,1,2))   
order_array = np.array(rows_list, dtype='object') 

In [72]: order_array 
Out[72]: 
array([[2008-01-23, AAPL, Buy, 100], 
     [2008-01-30, AAPL, Sell, 100], 
     [2008-01-23, GOOG, Buy, 100], 
     [2008-01-30, GOOG, Sell, 100], 
     [2008-09-08, GOOG, Buy, 100], 
     [2008-09-15, GOOG, Sell, 100], 
     [2008-05-01, XOM, Buy, 100], 
     [2008-05-08, XOM, Sell, 100]], dtype=object) 

यहां तक ​​कि इस हालांकि:

In [59]: import operator 

In [60]: rows_list.sort(key=operator.itemgetter(0,1,2)) 
Out[60]: 
[(2008, 1, 23, 'AAPL', 'Buy', 100), 
(2008, 1, 23, 'GOOG', 'Buy', 100), 
(2008, 1, 30, 'AAPL', 'Sell', 100), 
(2008, 1, 30, 'GOOG', 'Sell', 100), 
(2008, 5, 1, 'XOM', 'Buy', 100), 
(2008, 5, 8, 'XOM', 'Sell', 100), 
(2008, 9, 8, 'GOOG', 'Buy', 100), 
(2008, 9, 15, 'GOOG', 'Sell', 100)] 

order_array = np.array(rows_list, dtype='object') 

एक बेहतर विकल्प datetime.date वस्तुओं में पहले तीन स्तंभों गठबंधन करने के लिए किया जाएगा सरल है, मुझे dtype ऑब्जेक्ट के NumPy arrays पसंद नहीं है। आपको देशी dtypes के साथ नम्पी एरे के न तो गति और न ही मेमोरी स्पेस-सेविंग लाभ मिलता है। इस बिंदु पर आप सूचियों के पाइथन सूची के साथ काम कर सकते हैं और इससे निपटने के लिए वाक्य रचनात्मक रूप से आसान हो सकता है।


एक संरचित सरणी का उपयोग करना:

एक और अधिक NumPy-ish समाधान है जो अभी भी एक structured array (सजातीय सरणी के विपरीत) का उपयोग है गति और स्मृति लाभ प्रदान करता है । आप इस्तेमाल कर सकते हैं

dt = [('year', '<i4'), ('month', '<i4'), ('day', '<i4'), ('symbol', '|S8'), 
     ('action', '|S4'), ('value', '<i4')] 
order_array = np.array(rows_list, dtype=dt) 

In [47]: order_array.dtype 
Out[47]: dtype([('year', '<i4'), ('month', '<i4'), ('day', '<i4'), ('symbol', '|S8'), ('action', '|S4'), ('value', '<i4')]) 

संरचित सरणी सॉर्ट करने के लिए sort विधि: np.array के साथ एक संरचित सरणी बनाने के लिए आप स्पष्ट रूप से एक dtype देने की आवश्यकता होगी

order_array.sort(order=['year', 'month', 'day']) 

के साथ काम करने के लिए संरचित सरणी, आपको समरूप और संरचित सरणी के बीच कुछ अंतरों के बारे में जानने की आवश्यकता होगी:

आपका मूल समरूप सरणी 2-आयामी था। इसके विपरीत, सभी संरचित सरणियों 1-आयामी हैं:

In [51]: order_array.shape 
Out[51]: (8,) 

आप सूचकांक एक पूर्णांक के साथ संरचित सरणी या सरणी के माध्यम से पुनरावृति, आप वापस पाने तो पंक्तियों:

In [52]: order_array[3] 
Out[52]: (2008, 1, 30, 'GOOG', 'Sell', 100) 
सजातीय सरणियों के साथ

आप order_array[:, i] के साथ कॉलम तक पहुंच सकते हैं, अब एक संरचित सरणी के साथ, आप उन्हें नाम से एक्सेस करते हैं: उदाहरण के लिए order_array['year']


या, पांडा का उपयोग करें:

आप Pandas स्थापित कर सकते हैं, तो मुझे लगता है कि आप एक पांडा DataFrame साथ खुशी का काम कर रहे हो सकता है:

In [73]: df = pd.DataFrame(rows_list, columns=['date', 'symbol', 'action', 'value']) 
In [75]: df.sort(['date']) 
Out[75]: 
     date symbol action value 
0 2008-01-23 AAPL Buy 100 
2 2008-01-23 GOOG Buy 100 
1 2008-01-30 AAPL Sell 100 
3 2008-01-30 GOOG Sell 100 
6 2008-05-01 XOM Buy 100 
7 2008-05-08 XOM Sell 100 
4 2008-09-08 GOOG Buy 100 
5 2008-09-15 GOOG Sell 100 

पांडा timeseries संरेखित के लिए उपयोगी कार्य करता है तिथियों के अनुसार, गायब मूल्यों को भरना, समूह बनाना और एकत्र करना/पंक्तियों या स्तंभों को बदलना।


आम तौर पर यह वर्ष, माह, दिन के लिए तीन पूर्णांक मान कॉलम के बजाय एक ही तिथि स्तंभ के लिए अधिक उपयोगी है।

आप वर्ष, माह, दिन के रूप में अलग outputing के प्रयोजन के लिए कॉलम की जरूरत है, सीएसवी कहने के लिए है, तो आप इस तरह वर्ष, माह, दिन कॉलम के साथ तारीख स्तंभ की जगह ले सकते हैं:

In [33]: df = df.join(df['date'].apply(lambda x: pd.Series([x.year, x.month, x.day], index=['year', 'month', 'day']))) 

In [34]: del df['date'] 

In [35]: df 
Out[35]: 
    symbol action value year month day 
0 AAPL Buy 100 2008  1 23 
1 GOOG Buy 100 2008  1 23 
2 AAPL Sell 100 2008  1 30 
3 GOOG Sell 100 2008  1 30 
4 XOM Buy 100 2008  5 1 
5 XOM Sell 100 2008  5 8 
6 GOOG Buy 100 2008  9 8 
7 GOOG Sell 100 2008  9 15 

या, यदि आपके पास 'डेट' कॉलम के साथ शुरू करने के लिए कोई उपयोग नहीं है, तो आप निश्चित रूप से rows_list छोड़ सकते हैं और शुरुआत से वर्ष, महीने, दिन कॉलम के साथ डेटाफ्रेम बना सकते हैं। छंटाई अभी भी आसान है:

df.sort(['year', 'month', 'day']) 
+0

धन्यवाद। लेकिन मैं तारों को int में परिवर्तित कर रहा हूं। मैंने ऑर्डर_एरे बनाने के लिए कोड शामिल करने के लिए प्रश्न संपादित किया है। आपकी मदद के लिए तत्पर हैं – user2842122

+0

@ user2842122 - उन 'ints' को स्ट्रिंग में वापस परिवर्तित किया जा रहा है। unutbu - मुझे लगता है कि यहां सबसे सरल समाधान एक NumPy [डेटाटाइम ऑब्जेक्ट] (http://docs.scipy.org/doc/numpy/reference/arrays.datetime.html) और आपके शेष से बना एक न्यूपी रेयरेरे पेश करना हो सकता है स्ट्रिंग और पूर्णांक डेटा। यहां एक पूर्ण उदाहरण है [http://stackoverflow.com/a/16618557/122022)। –

+0

@AronAhmadia: टिप्पणी के लिए धन्यवाद! हां, मैं ऐसा कुछ जोड़ने की सोच रहा था, लेकिन मुझे डर है कि यह जवाब पहले से ही बहुत लंबा है, और पांडस अभी भी जाने का बेहतर तरीका है। – unutbu