2011-03-05 13 views
5

मैं bincount को सरणी के लिए उपयोग करना चाहता हूं, हालांकि यह केवल युगल का समर्थन करता है। उदाहरण के लिए इस काम करता है:सरणी वजन के साथ numpy.bincount का उपयोग

np.bincount([1, 1, 0],weights=np.array([[1,1], [2,2], [4,4]])) 
ValueError: object too deep for desired array 

वांछित आउटपुट है:

Out: array([[ 4., 4.],[3., 3.]]) 

टिप्पणियों के बाद बेहतर स्पष्टीकरण:

np.bincount([1, 1, 0],weights=np.array([1, 2, 4])) 
Out: array([ 4., 3.]) 

हालांकि मैं एक आयाम 2 सरणी का उपयोग करने के रूप में चाहते हैं

मैं सरणी की प्रत्येक पंक्ति को इसी अनुक्रमणिका में जोड़ना चाहता हूं।

एक पाश के साथ

यह होगा:

Bin=np.zeros(2,2) 
for i in [1,1,0]: 
    Bin[i]+=a[i] 

एक है पिछले 3x2 मैट्रिक्स इस परिणाम प्राप्त करने के लिए एक कारगर तरीका वहाँ है?

+0

क्या डिब्बे की संख्या तय है? कितने डिब्बे हैं? –

+0

इस संदर्भ में 'sum arrays' से आपका क्या मतलब है? यह आपके वांछित परिणाम के पीछे तर्क को समझने में मदद करेगा। – JoshAdel

+0

@ एंड्रिया: क्या आप कृपया मौखिक रूप से व्याख्या करने का प्रयास कर सकते हैं कि आप क्या लक्ष्य कर रहे हैं? चूंकि यह आपके कोड स्निपेट से वास्तव में स्पष्ट नहीं है। धन्यवाद – eat

उत्तर

3

प्रति numpy प्रलेखन के रूप में:

numpy.bincount(x, weights=None, minlength=None) 

वजन: array_like, वैकल्पिक; वजन, एक्स के समान आकार की सरणी।

तो आप इस फैशन में सीधे bincount उपयोग नहीं कर सकते जब तक कि आप किसी भी तरह x बदल देते हैं।

संपादित करें: तो मैं ऐसा करने का थोड़ा मुश्किल तरीका आया, लेकिन जब आप बड़े सरणी में जाते हैं तो प्रदर्शन के बारे में कोई गारंटी नहीं होती है। मूल रूप से मैं लाभ उठाने का तरीका scipy विरल मैट्रिक्स दोहराया एक ही सूचकांक में प्रविष्टियों संभाल जा रहा हूँ (वे उन्हें योग):

from scipy.sparse import * 
a = np.array([[1,1], [2,2], [4,4]]) 
ii = np.array([1, 1, 0]) 

ares = a.reshape((-1,),order='F') 
# ares == array([1, 2, 4, 1, 2, 4]) 

col = np.tile(ii,(a.shape[1],)) 
# col == np.array([1, 1, 0, 1, 1, 0]) 

row = np.tile([0,1],(a.shape[0],1)).reshape((-1,),order='F') 
# row == np.array([0,0,0,1,1,1]) 

g = coo_matrix((ares,(col,row)),shape=(2,2)) 
print g.todense()  

अब आप अपने सटीक डेटा को यह सामान्यीकरण करने के लिए करने जा रहे हैं। मूल विचार यह है कि आप प्रत्येक डेटा पॉइंट को अपने परिणाम सरणी के सही तत्व पर मैप करना चाहते हैं और फिर स्पैस सरणी को डुप्लिकेट प्रविष्टियों को एकत्रित करने दें।

अन्यथा, यदि आप इसे हल करने के लिए लूपिंग का उपयोग करने के लिए मजबूर हैं तो मैं साइथन का उपयोग करने के लिए देखता हूं।

संपादित करें 2: किक के लिए, मैं दो अलग अलग तरीकों का समय समाप्त हो:

import numpy as np 
from scipy.sparse import * 

def method1(): 
    return np.array([np.bincount(ii, r) for r in a.T]).T 

def method2(): 
    ares = a.reshape((-1,),order='F') 
    col = np.tile(ii,(a.shape[1],)) 
    row = np.tile(np.arange(a.shape[1]),(a.shape[0],1)).reshape((-1,),order='F') 

    return coo_matrix((ares,(col,row)),shape=(np.unique(ii).size,a.shape[1])).todense() 

if __name__ == '__main__': 
    from timeit import Timer 

    a = np.random.randint(0,1000,(1000000,3)) 
    ii = np.random.randint(0,10,(a.shape[0],)) 

    N = 100 
    t1 = Timer("method1()", "from __main__ import method1") 
    t2 = Timer("method2()", "from __main__ import method2") 
    print 't2/t1: %f' % (t2.timeit(N)/t1.timeit(N)) 

मेरी मशीन पर, method2 आदानों के आकार पर निर्भर करता है इसलिए पाशन नहीं है method1 से 3-5x के बारे में धीमी है जरूरी एक बुरा विकल्प।

+0

बिल्कुल, मैं इस –

+0

के लिए एक कुशल समाधान की तलाश में हूं, बहुत बहुत धन्यवाद, मैं इसका परीक्षण करूंगा और रिपोर्ट करूंगा। –

+0

@ एंड्रिया - आपको अब दो विधियों की तुलना की जांच करनी चाहिए जिन्हें मैंने अभी जोड़ा है। – JoshAdel

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