मैट्रिक्स की प्रत्येक पंक्ति में numpy.linalg.norm कैसे लागू करें?


82

मेरे पास 2 डी मैट्रिक्स है और मैं प्रत्येक पंक्ति का मानदंड लेना चाहता हूं। लेकिन जब मैं numpy.linalg.norm(X)सीधे उपयोग करता हूं , तो यह पूरे मैट्रिक्स का आदर्श लेता है।

मैं लूप का उपयोग करके प्रत्येक पंक्ति का मानदंड ले सकता हूं और फिर प्रत्येक का मान ले सकता हूं X[i], लेकिन मुझे 30k पंक्तियों के बाद बहुत बड़ा समय लगता है।

कोई रास्ता खोजने के लिए कोई सुझाव? या np.linalg.normमैट्रिक्स की प्रत्येक पंक्ति पर लागू करना संभव है ?

जवाबों:


87

ध्यान दें कि, पेरीमोसोकार्डिया शो के रूप में, NumPy संस्करण 1.9 के रूप में, np.linalg.norm(x, axis=1)L2- मानक की गणना करने का सबसे तेज़ तरीका है।


यदि आप L2- मान की गणना कर रहे हैं, तो आप इसे सीधे ( axis=-1पंक्तियों के साथ योग करने के तर्क का उपयोग करके) गणना कर सकते हैं :

np.sum(np.abs(x)**2,axis=-1)**(1./2)

एलपी-मानदंडों को इसी तरह से गणना की जा सकती है।

यह काफी तेजी से है np.apply_along_axis, हालांकि शायद उतना सुविधाजनक नहीं है:

In [48]: %timeit np.apply_along_axis(np.linalg.norm, 1, x)
1000 loops, best of 3: 208 us per loop

In [49]: %timeit np.sum(np.abs(x)**2,axis=-1)**(1./2)
100000 loops, best of 3: 18.3 us per loop

अन्य ordरूपों की normगणना सीधे भी की जा सकती है (समान स्पीडअप के साथ):

In [55]: %timeit np.apply_along_axis(lambda row:np.linalg.norm(row,ord=1), 1, x)
1000 loops, best of 3: 203 us per loop

In [54]: %timeit np.sum(abs(x), axis=-1)
100000 loops, best of 3: 10.9 us per loop

8
यदि आप x को किसी भी तरह से वर्ग करते हैं तो आप np.abs (x) क्यों करते हैं?
पैट्रिक

10
@ पैट्रिक: यदि dtype xजटिल है, तो इससे फर्क पड़ता है। उदाहरण के लिए, यदि x = np.array([(1+1j,2+1j)])तब np.sum(np.abs(x)**2,axis=-1)**(1./2)है array([ 2.64575131]), जबकि np.sum(x**2,axis=-1)**(1./2)है array([ 2.20320266+1.36165413j])
अनटुब

3
@perimosocordiae ने एक अपडेट पोस्ट किया कि numpy.linalg.normइसके नए axis तर्क के साथ वर्तमान में सबसे तेज़ दृष्टिकोण है।
Ioannis Filippidis

यदि मैं एक मैट्रिक्स पर मानक कॉलम-वार लागू करना चाहता हूं तो इसे कैसे करें?
गुंजन नाइक

@ user3515225 np.linalg.norm(x, axis=0):। axisसंदर्भित करता है के लिए अक्ष से अधिक अभिव्यक्त किया जा रहा है। 2 डी सरणी के लिए, 0-अक्ष पंक्तियों को संदर्भित करता है, इसलिए प्रत्येक निश्चित स्तंभ के लिए पंक्तियों को योग करने का axis=0कारण बनता normहै।
नौबत २३'१५ को

54

एक पुराने अद्यतन को सुन्न करने के कारण एक नया प्रश्न। 1.9 रिलीज के अनुसार, numpy.linalg.normअब एक axisतर्क स्वीकार करता है। [ कोड , प्रलेखन ]

यह शहर का सबसे नया तरीका है:

In [10]: x = np.random.random((500,500))

In [11]: %timeit np.apply_along_axis(np.linalg.norm, 1, x)
10 loops, best of 3: 21 ms per loop

In [12]: %timeit np.sum(np.abs(x)**2,axis=-1)**(1./2)
100 loops, best of 3: 2.6 ms per loop

In [13]: %timeit np.linalg.norm(x, axis=1)
1000 loops, best of 3: 1.4 ms per loop

और यह साबित करने के लिए कि यह उसी चीज़ की गणना कर रहा है:

In [14]: np.allclose(np.linalg.norm(x, axis=1), np.sum(np.abs(x)**2,axis=-1)**(1./2))
Out[14]: True

16

स्वीकृत उत्तर की तुलना में बहुत तेजी से NumPy के इिनसम का उपयोग कर रहा है ,

numpy.sqrt(numpy.einsum('ij,ij->i', a, a))

लॉग-स्केल पर ध्यान दें:

यहाँ छवि विवरण दर्ज करें


प्लॉट को फिर से तैयार करने के लिए कोड:

import numpy
import perfplot


def sum_sqrt(a):
    return numpy.sqrt(numpy.sum(numpy.abs(a) ** 2, axis=-1))


def apply_norm_along_axis(a):
    return numpy.apply_along_axis(numpy.linalg.norm, 1, a)


def norm_axis(a):
    return numpy.linalg.norm(a, axis=1)


def einsum_sqrt(a):
    return numpy.sqrt(numpy.einsum("ij,ij->i", a, a))


perfplot.show(
    setup=lambda n: numpy.random.rand(n, 3),
    kernels=[sum_sqrt, apply_norm_along_axis, norm_axis, einsum_sqrt],
    n_range=[2 ** k for k in range(20)],
    xlabel="len(a)",
)

2
यह समझाने के लिए कि क्या है / क्या है?
झिन

6

निम्नलिखित का प्रयास करें:

In [16]: numpy.apply_along_axis(numpy.linalg.norm, 1, a)
Out[16]: array([ 5.38516481,  1.41421356,  5.38516481])

aआपका 2D सरणी कहां है

उपरोक्त L2 मान की गणना करता है। एक अलग आदर्श के लिए, आप कुछ का उपयोग कर सकते हैं:

In [22]: numpy.apply_along_axis(lambda row:numpy.linalg.norm(row,ord=1), 1, a)
Out[22]: array([9, 2, 9])
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.