নম্প্পিতে আপনি কীভাবে কোনও ভেক্টরের পরিমাণ পাবেন?


157

"এটি করার একমাত্র সুস্পষ্ট উপায় আছে" এর সাথে তাল মিলিয়ে আপনি কীভাবে নম্প্পিতে কোনও ভেক্টরের (1 ডি অ্যারে) মাত্রা পাবেন?

def mag(x): 
    return math.sqrt(sum(i**2 for i in x))

উপরের কাজগুলি, তবে আমি বিশ্বাস করতে পারি না যে আমাকে অবশ্যই এ জাতীয় তুচ্ছ এবং মূল কার্য নির্দিষ্ট করতে হবে।


1
আমি সাধারণত linalg.normনীচে উল্লিখিত হিসাবে ব্যবহার করি । তবে আপনার ল্যাম্বদা জিনিসটির চেয়ে কিছুটা সহজ, কোনও আমদানির প্রয়োজন নেই, কেবলsum(x*x)**0.5
উইম

7
যাইহোক, কোনও নামের জন্য ল্যাম্বডা ফাংশন নির্ধারণের কোনও ভাল কারণ নেই।
wim

@ উইম কেন? আমি defযেমন একটি ফাংশন ঘোষণা করার সময় শুধুমাত্র ব্যবহার করা উচিত ? আমি মনে করি এটি যদি বৈধভাবে একটি লাইন হয় তবে এটি পড়া সহজ করে তোলে।
নিক টি

6
ল্যাম্বদা একটি বেনামি ফাংশন হ'ল তাই এটির একটি নাম দিয়ে আপনি এটি ভুল করছেন। এটি ডিএফ এর কেবলমাত্র একটি পঙ্গু সংস্করণ। এবং আপনি যদি জেদ করেন তবে আপনি একটি লাইনে একটি ডিফও রাখতে পারেন। ল্যাম্বডা ব্যবহার করার পক্ষে আপনি যে ন্যায়সঙ্গত হতে পারেন সেই সাধারণ জায়গাটি কোনও কলযোগ্য হিসাবে কিছু যুক্তির তালিকায় পাস করার জন্য। লোকেরা এটি উপরে দেখানো মত ভুল ব্যবহার করে এটি পাইথনের আক্ষেপের গাইডলোকের তালিকায় এটি তৈরি করার একটি কারণ (স্লাইড 4 দেখুন)
উইম

6
লিঙ্কটি মারা গেছে! লিংক লাইভ!
ডেভিউলেস

উত্তর:


209

আপনি পরে ফাংশন হয় numpy.linalg.norm। (আমি বিবেচনা করি এটি কোনও অ্যারের সম্পত্তি হিসাবে বেস ন্যাপি হওয়া উচিত - বলুন x.norm()- তবে ওহ ভাল)।

import numpy as np
x = np.array([1,2,3,4,5])
np.linalg.norm(x)

আপনি ordচান নবম অর্ডার আদর্শের জন্য আপনি একটি alচ্ছিকও খাওয়াতে পারেন। বলুন আপনি 1-আদর্শ চেয়েছিলেন:

np.linalg.norm(x,ord=1)

ইত্যাদি।


14
"অ্যারের সম্পত্তি হওয়া উচিত: x.norm ()" আমি পুরোপুরি একমত। সাধারণত নম্পিদের সাথে কাজ করার সময় আমি আমার নিজস্ব অ্যারে এবং ম্যাট্রিক্স সাবক্লাস ব্যবহার করি যা সমস্ত ফাংশন রয়েছে আমি সাধারণত পদ্ধতি হিসাবে টানতে ব্যবহার করি। Matrix.randn([5,5])
mdaoust

3
এছাড়াও, ভেক্টর গঠিত ম্যাট্রিক্স জন্য, np.linalg.normএখন একটি নতুন হয়েছে axis: যুক্তি, এখানে আলোচনা stackoverflow.com/a/19794741/1959808
Ioannis Filippidis

95

আপনি যদি গতি সম্পর্কে মোটেই চিন্তিত হন তবে আপনার পরিবর্তে এটি ব্যবহার করা উচিত:

mag = np.sqrt(x.dot(x))

এখানে কয়েকটি মানদণ্ড দেওয়া হল:

>>> import timeit
>>> timeit.timeit('np.linalg.norm(x)', setup='import numpy as np; x = np.arange(100)', number=1000)
0.0450878
>>> timeit.timeit('np.sqrt(x.dot(x))', setup='import numpy as np; x = np.arange(100)', number=1000)
0.0181372

সম্পাদনা করুন: যখন আপনাকে অনেক ভেক্টরের আদর্শ নিতে হয় তখন আসল গতির উন্নতি ঘটে। খাঁটি নপি ফাংশন ব্যবহারের জন্য লুপগুলির জন্য কোনও প্রয়োজন হয় না। উদাহরণ স্বরূপ:

In [1]: import numpy as np

In [2]: a = np.arange(1200.0).reshape((-1,3))

In [3]: %timeit [np.linalg.norm(x) for x in a]
100 loops, best of 3: 4.23 ms per loop

In [4]: %timeit np.sqrt((a*a).sum(axis=1))
100000 loops, best of 3: 18.9 us per loop

In [5]: np.allclose([np.linalg.norm(x) for x in a],np.sqrt((a*a).sum(axis=1)))
Out[5]: True

1
আমি আসলে np.linalg.normএটি একটি অটল আবিষ্কার করার পরে এই সামান্য-কম-স্পষ্ট পদ্ধতিটি ব্যবহার করেছি , কিন্তু তারপরে আমি আরও এক ধাপ এগিয়ে গিয়েছিলাম এবং এটি ব্যবহার করেছি math.sqrt(x[0]**2 + x[1]**2)যা ছিল আরও একটি উল্লেখযোগ্য উন্নতি।
নিক টি

@ নিকট, খাঁটি ন্যালি ফাংশন ব্যবহার করার সময় আসল উন্নতির জন্য আমার সম্পাদনাটি দেখুন।
ব্যবহারকারী545424

2
ডট পণ্য শীতল আবেদন!
ভিকেটেক

1
numpy.linalg.normওভারফ্লো বিরুদ্ধে সুরক্ষা রয়েছে যা এই প্রয়োগটি এড়িয়ে যায়। উদাহরণস্বরূপ, এর আদর্শ গণনা করার চেষ্টা করুন [1e200, 1e200]। যদি এটি ধীর হয় তবে একটি কারণ আছে ...
ফেডেরিকো পোলোনি

@ ফেডেরিকো পোলোনি, কমপক্ষে কমপক্ষে 1.13.3 সংস্করণ সহ infযখন আমি কম্পিউটিং করি তখনই পাই np.linalg.norm([1e200,1e200])
ব্যবহারকারীর 4545424

16

তবুও অন্য বিকল্পটি হ'ল einsumউভয় অ্যারেতে ফাংশনটি নাম্পায় ব্যবহার করা:

In [1]: import numpy as np

In [2]: a = np.arange(1200.0).reshape((-1,3))

In [3]: %timeit [np.linalg.norm(x) for x in a]
100 loops, best of 3: 3.86 ms per loop

In [4]: %timeit np.sqrt((a*a).sum(axis=1))
100000 loops, best of 3: 15.6 µs per loop

In [5]: %timeit np.sqrt(np.einsum('ij,ij->i',a,a))
100000 loops, best of 3: 8.71 µs per loop

বা ভেক্টর:

In [5]: a = np.arange(100000)

In [6]: %timeit np.sqrt(a.dot(a))
10000 loops, best of 3: 80.8 µs per loop

In [7]: %timeit np.sqrt(np.einsum('i,i', a, a))
10000 loops, best of 3: 60.6 µs per loop

তবে এটি বলার সাথে কিছু ওভারহেড যুক্ত বলে মনে হচ্ছে যা এটি ছোট ইনপুটগুলির সাহায্যে ধীর করে দিতে পারে:

In [2]: a = np.arange(100)

In [3]: %timeit np.sqrt(a.dot(a))
100000 loops, best of 3: 3.73 µs per loop

In [4]: %timeit np.sqrt(np.einsum('i,i', a, a))
100000 loops, best of 3: 4.68 µs per loop

numpy.linalg.normওভারফ্লো বিরুদ্ধে সুরক্ষা রয়েছে যা এই প্রয়োগটি এড়িয়ে যায়। উদাহরণস্বরূপ, এর আদর্শ গণনা করার চেষ্টা করুন [1e200, 1e200]। যদি এটি ধীর হয় তবে একটি কারণ আছে ...
ফেডেরিকো পোলোনি

7

আমি খুঁজে পাওয়া দ্রুততমতম উপায়টি অভ্যন্তরীণ 1 ডি এর মাধ্যমে। এটি অন্যান্য অপ্রয়োজনীয় পদ্ধতির সাথে কীভাবে তুলনা করে তা এখানে:

import numpy as np
from numpy.core.umath_tests import inner1d

V = np.random.random_sample((10**6,3,)) # 1 million vectors
A = np.sqrt(np.einsum('...i,...i', V, V))
B = np.linalg.norm(V,axis=1)   
C = np.sqrt((V ** 2).sum(-1))
D = np.sqrt((V*V).sum(axis=1))
E = np.sqrt(inner1d(V,V))

print [np.allclose(E,x) for x in [A,B,C,D]] # [True, True, True, True]

import cProfile
cProfile.run("np.sqrt(np.einsum('...i,...i', V, V))") # 3 function calls in 0.013 seconds
cProfile.run('np.linalg.norm(V,axis=1)')              # 9 function calls in 0.029 seconds
cProfile.run('np.sqrt((V ** 2).sum(-1))')             # 5 function calls in 0.028 seconds
cProfile.run('np.sqrt((V*V).sum(axis=1))')            # 5 function calls in 0.027 seconds
cProfile.run('np.sqrt(inner1d(V,V))')                 # 2 function calls in 0.009 seconds

ইনার 1 ডি লিনালগ.অনরমের চেয়ে ~ 3x দ্রুত এবং আইনম থেকে একটি চুল দ্রুত


প্রকৃতপক্ষে আপনি যা লিখেছেন তা থেকে linalg.normদ্রুততম, যেহেতু এটি 29 মেমসে 9 কল করে তাই 3.222ms এ 1 কল এবং বনাম 1 ম কল 4.4 মিমি জন্য inner1d
patapouf_ai

@ বিজনাউন্টস_ট্রোকন মোট মৃত্যুর সময় নির্ধারণের সময়টি ব্যবহার করুন। যদি আপনি উপরের কোডটি চালান তবে আপনি ফাংশন কল প্রতি সময়সীমার ব্রেকডাউন পাবেন। যদি আপনার এখনও সন্দেহ থাকে তবে ভেক্টর সংখ্যাটি খুব বড় কিছুতে পরিবর্তন করুন, পছন্দ করুন ((10**8,3,))এবং তারপরে ম্যানুয়ালি np.linalg.norm(V,axis=1)অনুসরণ করুন np.sqrt(inner1d(V,V)), আপনি খেয়াল linalg.normকরবেন
অভ্যন্তরীণ

ঠিক আছে. সুস্পষ্ট করার জন্য ধন্যবাদ.
patapouf_ai

numpy.linalg.normওভারফ্লো বিরুদ্ধে সুরক্ষা রয়েছে যা এই প্রয়োগটি এড়িয়ে যায়। উদাহরণস্বরূপ, এর আদর্শ গণনা করার চেষ্টা করুন [1e200, 1e200]। যদি এটি ধীর হয় তবে একটি কারণ আছে ...
ফেডেরিকো পোলোনি

3

ফাংশন ব্যবহার আদর্শ মধ্যে scipy.linalg (অথবা numpy.linalg )

>>> from scipy import linalg as LA
>>> a = 10*NP.random.randn(6)
>>> a
  array([  9.62141594,   1.29279592,   4.80091404,  -2.93714318,
          17.06608678, -11.34617065])
>>> LA.norm(a)
    23.36461979210312

>>> # compare with OP's function:
>>> import math
>>> mag = lambda x : math.sqrt(sum(i**2 for i in x))
>>> mag(a)
     23.36461979210312

1

আপনি সংক্ষেপে toolbelt ব্যবহার করে এই কাজ করতে পারেন VG । এটি নমপির শীর্ষে একটি হালকা স্তর এবং এটি একক মান এবং স্ট্যাকড ভেক্টরগুলিকে সমর্থন করে।

import numpy as np
import vg

x = np.array([1, 2, 3, 4, 5])
mag1 = np.linalg.norm(x)
mag2 = vg.magnitude(x)
print mag1 == mag2
# True

আমি আমার শেষ প্রারম্ভে লাইব্রেরিটি তৈরি করেছি, যেখানে এটি এই জাতীয় ব্যবহারের দ্বারা অনুপ্রাণিত হয়েছিল: সাধারণ ধারণা যা নুমপাইতে খুব বেশি ভার্জোজ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.