2017-07-08 9 views
5

मैं एक numpy सरणी बनाना चाहता हूं जिसमें एक विशिष्ट स्थान पर कितनी बार एक मान (1-3 के बीच) होता है। उदाहरण के लिए, अगर मेरे पास है:गणना की एक संख्यात्मक सरणी संपादित करने के लिए एक लाइन समाधान? (पायथन)

a = np.array([[1,2,3], 
       [3,2,1], 
       [2,1,3], 
       [1,1,1]]) 

मैं बहुत की तरह एक सरणी वापस प्राप्त करना चाहते हैं:

[[[ 1 0 0] 
    [ 0 1 0] 
    [ 0 0 1]] 

[[ 0 0 1] 
    [ 0 1 0] 
    [ 1 0 0]] 

[[ 0 1 0] 
    [ 1 0 0] 
    [ 0 0 1]] 

[[ 1 0 0] 
    [ 1 0 0] 
    [ 1 0 0]]] 

कहाँ सरणी मुझसे कहता है कि 1 पहले की स्थिति में एक बार होता है, 2 में एक बार होता है दूसरी स्थिति, 3 तीसरी स्थिति में एक बार होती है, 1 चौथी स्थिति में एक बार होता है, आदि। बाद में, मेरे पास समान आयामों के अधिक इनपुट एरे होंगे, और मैं इस सरणी के मानों के योगों को जोड़ना चाहता हूं मायने रखता है

कोड मैं अभी है:

a = np.array([[1,2,3], 
       [3,2,1], 
       [2,1,3], 
       [1,1,1]]) 

cumulative = np.zeros((4,3,3)) 

for r in range(len(cumulative)): 
    for c in range(len(cumulative[0])): 
     cumulative[r, c, a[r,c]-1] +=1 

यह मैं उत्पादन मैं चाहता हूँ देता है। काम नहीं करता है

cumulative[:, :, a[:, :]-1] +=1 

इस लाइन, और मैं कुछ भी ऑनलाइन कैसे यह कार्रवाई करने पर नहीं मिल सकता है: हालांकि, मैं एक लाइन में छोरों के लिए गाढ़ा करने के लिए, एक पंक्ति इस के समान का उपयोग कर चाहते हैं। कोई सुझाव?

उत्तर

3

IIUC एक मिलान संख्या के सूचकांकों सेट को भरने के लिए प्रयोग किया जाता है:

In [93]: ((a[:, None] - 1) == np.arange(3)[:, None]).swapaxes(2, 1).astype(int) 
Out[93]: 
array([[[1, 0, 0], 
     [0, 1, 0], 
     [0, 0, 1]], 

     [[0, 0, 1], 
     [0, 1, 0], 
     [1, 0, 0]], 

     [[0, 1, 0], 
     [1, 0, 0], 
     [0, 0, 1]], 

     [[1, 0, 0], 
     [1, 0, 0], 
     [1, 0, 0]]]) 
+0

यह अच्छा है! क्या आप समझेंगे कि यह कैसे काम करता है? (क्षमा करें, पाइथन के लिए अपेक्षाकृत नया) –

1

यह तकनीकी रूप से एक लाइनर नहीं है, लेकिन यदि आप PEP 8's maximum line length को अनदेखा करते हैं तो आप इसे दो पंक्तियों तक कम कर सकते हैं।

a = np.array([[1,2,3], 
       [3,2,1], 
       [2,1,3], 
       [1,1,1]]) 

out = np.zeros((a.shape[0], 1 + a.max() - a.min(), a.shape[1]), dtype=np.int8) 
out[np.repeat(np.arange(a.shape[0]), a.shape[1]), np.subtract(
    a, a.min())[:].flatten(), np.tile(np.arange(a.shape[1]), a.shape[0])] = 1 
print(out) 

आउटपुट कौन सा;

[[[1 0 0] 
    [0 1 0] 
    [0 0 1]] 

[[0 0 1] 
    [0 1 0] 
    [1 0 0]] 

[[0 1 0] 
    [1 0 0] 
    [0 0 1]] 

[[1 0 0] 
    [1 0 0] 
    [1 0 0]]] 

यह शायद नहीं सबसे Gainly है और न ही सुंदर समाधान n आयामों को स्केल नहीं करता है, और दुर्भाग्य से, लेकिन उम्मीद है कि इस (लगभग एक लाइनर) पर्याप्त रूप से आप के लिए vectorised है।


यह तो मैं संक्षेप में यह कैसे काम करता माध्यम से चलाने जाएगा काफी मोटी है।

  • उत्पादन सरणी की कुल लंबाई के साथ डिफ़ॉल्ट रूप से शून्य से भरा बनाया गया है, 'एक गर्म वैक्टर' इनपुट सरणी (मैं इस ग्रहण की सीमा के बराबर है कि तुम क्या दिया चाहता था कि आपके उदाहरण में दिए गए मान शून्य के लिए कोई पंक्ति नहीं)।

  • np.tile और np.repeatnp.arange साथ किया जाता है पहली और आखिरी सूचकांक सरणियों निर्माण करने के लिए, कि a में प्रत्येक तत्व के सूचकांक है।

  • फैंसी indicing आप प्रसारण का लाभ ले सकता है, 1.

1
np.concatenate((a==1,a==2,a==3),axis=1).reshape((4,3,3)).transpose(0,2,1) + 0 
संबंधित मुद्दे