Numpy: प्रत्येक पंक्ति को वेक्टर तत्व द्वारा विभाजित करें


119

मान लीजिए कि मेरे पास एक सुरीली सरणी है:

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

और मेरे पास एक "वेक्टर:" है

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

मैं dataप्रत्येक पंक्ति के साथ कैसे घटाना या विभाजित करना चाहता हूँ , परिणाम है:

sub_result = [[0,0,0], [0,0,0], [0,0,0]]
div_result = [[1,1,1], [1,1,1], [1,1,1]]

लंबी कहानी छोटी: मैं 1 डी सरणी के साथ 2 डी सरणी की प्रत्येक पंक्ति पर एक ऑपरेशन कैसे करूं जो प्रत्येक पंक्ति के अनुरूप हो?

जवाबों:


181

हेयर यू गो। आपको बस प्रसारण के साथ संयुक्त Noneरूप से (या वैकल्पिक रूप से np.newaxis) उपयोग करने की आवश्यकता है :

In [6]: data - vector[:,None]
Out[6]:
array([[0, 0, 0],
       [0, 0, 0],
       [0, 0, 0]])

In [7]: data / vector[:,None]
Out[7]:
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])

13
यहाँ डॉक्टर है।
सैजरी


@ user108569 सुन्न (1.18.1) के नवीनतम संस्करण का उपयोग करते हुए, Noneअभी भी बराबर काम करता है np.newaxis। मुझे यकीन नहीं है कि आपका सेटअप क्या है, या आपके द्वारा अनुभव किया जा रहा सटीक मुद्दा है, लेकिन उत्तर अभी भी मान्य है।
जोशेल

11

जैसा कि उल्लेख किया गया है, ऐसा करने के लिए Noneया उसके साथ टुकड़ा करना np.newaxesएक शानदार तरीका है। एक अन्य विकल्प के रूप में संक्रमण और प्रसारण का उपयोग करना है

(data.T - vector).T

तथा

(data.T / vector).T

उच्च आयामी सरणियों के लिए आप swapaxesNumPy सरणियों या NumPy rollaxisफ़ंक्शन की विधि का उपयोग करना चाह सकते हैं । ऐसा करने के लिए वास्तव में बहुत सारे तरीके हैं।

प्रसारण की पूरी व्याख्या के लिए, http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html देखें


4

जोश एडेल का समाधान आयाम जोड़ने के लिए np.newaxis का उपयोग करता है। प्रसारण के लिए तैयारी में आयामों को संरेखित करने के लिए एक विकल्प reshape () का उपयोग करना है

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

data
# array([[1, 1, 1],
#        [2, 2, 2],
#        [3, 3, 3]])
vector
# array([1, 2, 3])

data.shape
# (3, 3)
vector.shape
# (3,)

data / vector.reshape((3,1))
# array([[1, 1, 1],
#        [1, 1, 1],
#        [1, 1, 1]])

प्रदर्शन () प्रसारण के लिए लाइन अप करने के लिए आयाम की अनुमति देता है:

data:            3 x 3
vector:              3
vector reshaped: 3 x 1

ध्यान दें कि data/vectorयह ठीक है, लेकिन यह आपको वह उत्तर नहीं मिलता जो आप चाहते हैं। यह प्रत्येक तत्व के प्रत्येक कॉलम को array(प्रत्येक पंक्ति के बजाय ) विभाजित करता है vector। यदि आपको इसके बदले स्पष्ट रूप vectorसे बदलने की आवश्यकता है, तो यह आपको मिलेगा ।1x33x1

data / vector
# array([[1, 0, 0],
#        [2, 1, 0],
#        [3, 1, 1]])
data / vector.reshape((1,3))
# array([[1, 0, 0],
#        [2, 1, 0],
#        [3, 1, 1]])

2

ऐसा करने का पाइथोनिक तरीका है ...

np.divide(data.T,vector).T

यह पुनर्वसन का ध्यान रखता है और परिणाम भी फ्लोटिंग पॉइंट फॉर्मेट में होते हैं। अन्य उत्तरों में परिणाम पूर्णांक पूर्णांक प्रारूप में होते हैं।

# नोट: डेटा और वेक्टर दोनों में कोई भी कॉलम मेल नहीं खाना चाहिए


नोट: यह वह नहीं करता है जो ओपी अनुरोध कर रहा है। अंतिम परिणाम सरणी ([[1, 0.5, 0.33333333]], [2., 1., 0.66666667], [3., 1.5, 1.]] है। यह 'Pythonic' हो सकता है लेकिन यह गलत है।
मार्क क्रैमर

1
@MarkCramer धन्यवाद। मैंने सही परिणाम प्रदान करने के लिए अपना उत्तर सही किया है।
शांतनु पाठक

1

Stackoverflowuser2010 के उत्तर में जोड़ना, सामान्य मामले में आप बस उपयोग कर सकते हैं

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

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

data / vector.reshape(-1,1)

यह आपके वेक्टर को एक में बदल देगा column matrix/vector। जैसा आप चाहते हैं, वैसे तत्वों के संचालन के लिए आपको अनुमति देना। कम से कम मेरे लिए, यह इसके बारे में जाने वाला सबसे सहज तरीका है और चूंकि (ज्यादातर मामलों में) सुन्न सिर्फ उसी आंतरिक मेमोरी के दृश्य का उपयोग करेगा, जो इसे फिर से तैयार करने के लिए भी कुशल है।


यह स्वीकृत उत्तर होना चाहिए। .reshape(-1,1) ब्रॉडकास्टिंग का उपयोग करने के लिए सबसे आसान तरीका है एक कॉलम वेक्टर बनाना ।
पॉल रूजियक्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.