2016-08-04 11 views
5

एरेपी बनाने के दौरान NumPy वास्तव में सहायक होता है। यदि numpy.array के लिए पहली तर्क __getitem__ और __len__ विधि है, तो इनका उपयोग इस आधार पर किया जाता है कि यह एक वैध अनुक्रम हो सकता है।एक बहुआयामी सरणी बनाने से numpy को रोकें

दुर्भाग्यवश मैं न्यूमपी को "सहायक" होने के बिना dtype=object युक्त एक सरणी बनाना चाहता हूं।

एक न्यूनतम उदाहरण के लिए नीचे टूटी वर्ग इस चाहते हैं:

import numpy as np 

class Test(object): 
    def __init__(self, iterable): 
     self.data = iterable 

    def __getitem__(self, idx): 
     return self.data[idx] 

    def __len__(self): 
     return len(self.data) 

    def __repr__(self): 
     return '{}({})'.format(self.__class__.__name__, self.data) 

और अगर "iterables" है अलग-अलग लंबाई सब कुछ ठीक है और मैं वास्तव में परिणाम मैं करना चाहते हैं मिलता है:

>>> np.array([Test([1,2,3]), Test([3,2])], dtype=object) 
array([Test([1, 2, 3]), Test([3, 2])], dtype=object) 

लेकिन अगर ये एक ही लंबाई के लिए हो NumPy एक बहुआयामी सरणी बनाता है:

>>> np.array([Test([1,2,3]), Test([3,2,1])], dtype=object) 
array([[1, 2, 3], 
     [3, 2, 1]], dtype=object) 

दुर्भाग्य से केवल ndmin तर्क है इसलिए मैं सोच रहा था कि ndmax को लागू करने का कोई तरीका है या किसी भी तरह से कस्टम वर्गों को किसी अन्य आयाम के रूप में समझने से न्यूमपी को रोकें (__len__ या __getitem__ को हटाए बिना)?

उत्तर

3

का संभावित हल वांछित आकार की एक सरणी बनाने के लिए और फिर डेटा की प्रतिलिपि निश्चित रूप से है:

In [19]: lst = [Test([1, 2, 3]), Test([3, 2, 1])] 

In [20]: arr = np.empty(len(lst), dtype=object) 

In [21]: arr[:] = lst[:] 

In [22]: arr 
Out[22]: array([Test([1, 2, 3]), Test([3, 2, 1])], dtype=object) 

ध्यान दें कि किसी भी मामले में मैं आश्चर्य नहीं होगा अगर numpy व्यवहार w.r.t. पुनरावृत्त वस्तुओं की व्याख्या करना (जो आप उपयोग करना चाहते हैं, है ना?) numpy संस्करण निर्भर है। और संभवतः छोटी गाड़ी। या शायद इनमें से कुछ कीड़े वास्तव में विशेषताएं हैं। वैसे भी, जब एक numpy संस्करण बदलता है तो मैं टूटने से सावधान रहूंगा।

इसके विपरीत, पूर्व-निर्मित सरणी में प्रतिलिपि बनाना अधिक मजबूत होना चाहिए।

5

इस व्यवहार पर कई बार चर्चा की गई है (उदा। Override a dict with numpy support)। np.array उच्च आयामी सरणी के रूप में बनाने की कोशिश करता है जैसा कि यह कर सकता है। मॉडल केस नेस्टेड सूचियां हैं। यदि यह पुनरावृत्त हो सकता है और उपन्यास लंबाई में बराबर हैं तो यह नीचे 'ड्रिल' होगा। किसी आकार या ndmax पैरामीटर यह जानने के लिए कि क्या मैं इसे (2,) या (2,2) होना चाहते हैं का कोई रास्ता नहीं है बिना

In [250]: np.array([[[1,2],[3]],[1,2]],dtype=object) 
Out[250]: 
array([[[1, 2], [3]], 
     [1, 2]], dtype=object) 
In [251]: _.shape 
Out[251]: (2, 2) 

:

यहाँ यह अलग लंबाई की सूची का सामना करने से पहले 2 स्तर नीचे चला गया। वे दोनों dtype के साथ काम करेंगे।

यह संकलित कोड है, इसलिए यह देखना आसान नहीं है कि यह वास्तव में कौन से परीक्षणों का उपयोग करता है। यह सूचियों और tuples पर पुन: प्रयास करने की कोशिश करता है, लेकिन सेट या शब्दकोश पर नहीं।

किसी दिए गए आयाम के साथ एक वस्तु सरणी बनाने के लिए सबसे पक्का तरीका एक खाली एक के साथ शुरू करते हैं, और भरने यह

In [266]: A=np.empty((2,3),object) 
In [267]: A.fill([[1,'one']]) 
In [276]: A[:]={1,2} 
In [277]: A[:]=[1,2] # broadcast error 

एक और तरीका है कम से कम एक अलग तत्व के साथ शुरू करने के लिए है करने के लिए है (उदाहरण के लिए एक None) , और उसके बाद इसे प्रतिस्थापित करें।

वहाँ एक अधिक आदिम निर्माता है, ndarray कि आकार लेता है:

In [280]: np.ndarray((2,3),dtype=object) 
Out[280]: 
array([[None, None, None], 
     [None, None, None]], dtype=object) 

लेकिन वह मूल रूप से np.empty के समान होता है (जब तक कि मैं इसे एक बफर दें)।

ये फज हैं, लेकिन वे महंगे (समय के अनुसार) नहीं हैं।

================ (संपादित)

https://github.com/numpy/numpy/issues/5933, Enh: Object array creation function. बढ़ा हुआ अनुरोध है। https://github.com/numpy/numpy/issues/5303the error message for accidentally irregular arrays is confusing भी।

डेवलपर भावना dtype=object सरणी बनाने के लिए एक अलग फ़ंक्शन का पक्ष लेती है, जिसमें प्रारंभिक आयामों और पुनरावृत्ति की गहराई पर अधिक नियंत्रण होता है। वे 'अनियमित' सरणी बनाने से np.array रखने के लिए त्रुटि जांच को भी मजबूत कर सकते हैं।

इस तरह का एक फ़ंक्शन नियमित नेस्टेड के आकार को एक निर्दिष्ट गहराई तक पहचान सकता है, और भरने के लिए ऑब्जेक्ट प्रकार सरणी का निर्माण कर सकता है।

def objarray(alist, depth=1): 
    shape=[]; l=alist 
    for _ in range(depth): 
     shape.append(len(l)) 
     l = l[0] 
    arr = np.empty(shape, dtype=object) 
    arr[:]=alist 
    return arr 
विभिन्न गहराई के साथ

:

In [528]: alist=[[Test([1,2,3])], [Test([3,2,1])]] 
In [529]: objarray(alist,1) 
Out[529]: array([[Test([1, 2, 3])], [Test([3, 2, 1])]], dtype=object) 
In [530]: objarray(alist,2) 
Out[530]: 
array([[Test([1, 2, 3])], 
     [Test([3, 2, 1])]], dtype=object) 
In [531]: objarray(alist,3) 
Out[531]: 
array([[[1, 2, 3]], 

     [[3, 2, 1]]], dtype=object) 
In [532]: objarray(alist,4) 
... 
TypeError: object of type 'int' has no len() 
+0

मैं इसी तरह के सवाल की तलाश करने की कोशिश की, लेकिन मैं किसी भी नहीं मिला है। शायद मैंने अभी गलत वाक्यांशों की खोज की है। यदि आपके पास पहले के प्रश्नों का कोई संदर्भ है जो बहुत अच्छा होगा। उत्तर के लिए धन्यवाद लेकिन मैं वास्तव में एक कामकाज की तलाश नहीं कर रहा हूं। मुझे एक और सामान्य दृष्टिकोण में अधिक दिलचस्पी है कि मैं सरणी की अधिकतम गहराई (आयाम) को परिभाषित करता हूं कि बिना किसी सटीक लंबाई को जानने के पहले या निष्क्रिय करने के लिए कस्टम क्लास उदाहरण अनुक्रम के रूप में व्याख्या करता है। – MSeifert

+0

अपनी कक्षा को उप-वर्ग 'dict' में बदलकर मैं इसे अपने उदाहरणों पर पुन: स्थापित करने से रोक सकता हूं। यह एक संकेत है कि 'np.array'' __getitem__' से अधिक के लिए परीक्षण कर रहा है। लेकिन मैं उस कोड को खोजने में सक्षम नहीं हूं जो उस तरह की जांच करता है। – hpaulj

+0

http://stackoverflow.com/questions/36663919/override-a-dict-with-numpy-support - एक ही मुद्दे के साथ संघर्ष; यह नियंत्रित करना कि 'np.array' आपकी कस्टम कक्षा पर पुनरावृत्ति करता है या नहीं। आसपास के काम के समान प्रकार। – hpaulj

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