अजगर कम क्रिया में 2-आयामी सुन्न सरणी को सामान्य कैसे करें?


87

3 गुना 3 अंक की सरणी दी

a = numpy.arange(0,27,3).reshape(3,3)

# array([[ 0,  3,  6],
#        [ 9, 12, 15],
#        [18, 21, 24]])

मैंने सोचा 2-आयामी सरणी की पंक्तियों को सामान्य करने के लिए

row_sums = a.sum(axis=1) # array([ 9, 36, 63])
new_matrix = numpy.zeros((3,3))
for i, (row, row_sum) in enumerate(zip(a, row_sums)):
    new_matrix[i,:] = row / row_sum

वहाँ एक बेहतर तरीका होना चाहिए, वहाँ नहीं है?

शायद स्पष्ट करने के लिए: मेरा मतलब सामान्य करने से, प्रति पंक्ति प्रविष्टि का योग एक होना चाहिए। लेकिन मुझे लगता है कि ज्यादातर लोगों के लिए यह स्पष्ट होगा।


16
सावधान, "सामान्यीकृत" का मतलब आमतौर पर घटकों का वर्ग योग एक होता है। आपकी परिभाषा शायद ही अधिकांश लोगों को स्पष्ट होगी;)
कोल्डफिक्स

जवाबों:


137

इसके लिए प्रसारण वास्तव में अच्छा है:

row_sums = a.sum(axis=1)
new_matrix = a / row_sums[:, numpy.newaxis]

row_sums[:, numpy.newaxis]reshapes row_sums होने (3,)से (3, 1)। जब आप करते हैं a / b, aऔर bएक दूसरे के खिलाफ प्रसारित होते हैं।

आप के बारे में अधिक सीख सकते हैं प्रसारण यहाँ या और भी बेहतर यहाँ


27
इसे a.sum(axis=1, keepdims=True)सिंगलटन कॉलम के आयाम को बनाए रखने के लिए आगे भी उपयोग करके सरल बनाया जा सकता है , जिसे आप बाद में उपयोग किए बिना प्रसारित कर सकते हैं np.newaxis
अली_म

6
क्या होगा यदि पंक्ति_समों में से कोई भी शून्य हो?
asdf

7
यह प्रश्न के लिए सही उत्तर है जैसा कि ऊपर कहा गया है - लेकिन अगर सामान्य अर्थों में एक सामान्यीकरण वांछित है, तो np.linalg.normइसके बजाय का उपयोग करें a.sum!
कोल्डफिक्स

1
क्या यह पसंद किया जाता है row_sums.reshape(3,1)?
पॉल

1
यह उतना मजबूत नहीं है क्योंकि पंक्ति योग 0.
nos

103

स्किकिट-लर्न में एक सामान्यीकृत फ़ंक्शन होता है जो आपको विभिन्न सामान्यीकरण लागू करने देता है। "इसे 1 के लिए योग करें" L1 मानदंड है, और इसे करने के लिए:

from sklearn.preprocessing import normalize
matrix = numpy.arange(0,27,3).reshape(3,3).astype(numpy.float64)

#array([[  0.,   3.,   6.],
#   [  9.,  12.,  15.],
#   [ 18.,  21.,  24.]])

normed_matrix = normalize(matrix, axis=1, norm='l1')

#[[ 0.          0.33333333  0.66666667]
#[ 0.25        0.33333333  0.41666667]
#[ 0.28571429  0.33333333  0.38095238]]

अब आपकी पंक्तियों का योग 1 हो जाएगा।


3
यह भी फायदा है कि यह विरल सरणियों पर काम करता है जो घने सरणियों के रूप में स्मृति में फिट नहीं होगा।
JEM_Mosig

10

मुझे लगता है कि यह काम करना चाहिए,

a = numpy.arange(0,27.,3).reshape(3,3)

a /=  a.sum(axis=1)[:,numpy.newaxis]

2
अच्छा। दशमलव बिंदु को 27 तक जोड़कर, att को बदलने की व्यवस्था पर ध्यान दें।
wim

3

यदि आप प्रत्येक पंक्ति को सामान्य बनाने की कोशिश कर रहे हैं, तो इसका परिमाण एक है (यानी एक पंक्ति की इकाई की लंबाई एक है या एक पंक्ति में प्रत्येक तत्व के वर्ग का योग एक है):

import numpy as np

a = np.arange(0,27,3).reshape(3,3)

result = a / np.linalg.norm(a, axis=-1)[:, np.newaxis]
# array([[ 0.        ,  0.4472136 ,  0.89442719],
#        [ 0.42426407,  0.56568542,  0.70710678],
#        [ 0.49153915,  0.57346234,  0.65538554]])

सत्यापित किया जा रहा:

np.sum( result**2, axis=-1 )
# array([ 1.,  1.,  1.]) 

एक्सिस np.linalg.norm (अब और?) के लिए एक पैरामीटर नहीं लगता है।
Ztyx

विशेष रूप से यह l2 मानदंड से मेल खाता है (जहाँ पंक्तियाँ 1 के बराबर हैं l1 मानदंड से मेल खाती हैं)
dpb

3

मुझे लगता है कि आप इसके द्वारा पंक्ति के योग 1 को सामान्य कर सकते हैं new_matrix = a / a.sum(axis=1, keepdims=1):। और कॉलम सामान्यीकरण के साथ किया जा सकता है new_matrix = a / a.sum(axis=0, keepdims=1)। आशा है कि यह हेप कर सकता है।



1

ऐसा प्रतीत होता है कि यह भी काम करता है

def normalizeRows(M):
    row_sums = M.sum(axis=1)
    return M / row_sums

1

आप मैट्रिक्स ट्रांसपोज़िशन का उपयोग भी कर सकते हैं:

(a.T / row_sums).T

0

या लाम्बा फ़ंक्शन का उपयोग करना, जैसे

>>> vec = np.arange(0,27,3).reshape(3,3)
>>> import numpy as np
>>> norm_vec = map(lambda row: row/np.linalg.norm(row), vec)

vec के प्रत्येक वेक्टर में एक यूनिट मानदंड होगा।


-2
normed_matrix = normalize(input_data, axis=1, norm='l1')
print(normed_matrix)

जहाँ input_data आपके 2D सरणी का नाम है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.