Wektoryzacja i rozgłaszanie w Pythonie

Opublikowany: 2020-12-01

Wektoryzacja i rozgłaszanie to sposoby na przyspieszenie czasu obliczeniowego i optymalizację wykorzystania pamięci podczas wykonywania operacji matematycznych za pomocą Numpy. Metody te mają kluczowe znaczenie dla zmniejszenia złożoności czasowej, tak aby algorytmy nie napotykały żadnych wąskich gardeł. Ta zoptymalizowana operacja jest niezbędna, aby aplikacje były skalowalne. Omówimy obie te techniki i zaimplementujemy kilka przykładów.

Pod koniec tego samouczka zdobędziesz wiedzę w zakresie:

  • Jak wektoryzacja jest obsługiwana przez Numpy
  • Różnice czasu z wektoryzacją i bez niej
  • Czym jest nadawanie
  • Czym nadawanie różni się od zwykłego mnożenia macierzy

Wektoryzacja

Często wymagamy operacji matematycznych na tablicach – takich jak mnożenie tablic. Teraz niewektoryzowanym sposobem byłoby mnożenie elementów za pomocą pętli. Zaimplementowanie go w taki sposób spowodowałoby, że ta sama operacja mnożenia byłaby wykonywana wiele razy, co byłoby marnotrawstwem zasobów obliczeniowych, jeśli rozmiar danych byłby zbyt duży. Rzućmy okiem.

Niewektoryzowany sposób:

Importuj losowo

a = [losowy.randint( 1 , 100 ) dla _ w zakresie( 10000 )]
b = [losowy.randint( 1 , 100 ) dla _ w zakresie( 10000 )]
%timeit [i*j dla i, j w zip(a,b)]

#Wyjście:
>> 1000 pętli, najlepiej 3 : 658 µs na pętlę

Zwektoryzowany sposób:

importuj numer jako np
a = np. tablica([losowe.randint( 1 , 100 ) dla _ w zakresie ( 10000 )])
b = np. tablica([losowe.randint( 1 , 100 ) dla _ w zakresie ( 10000 )])
%timeit a*b

#Wyjście:
>> 100000 pętli, najlepsze z 3 : 7,25 µs na pętlę

Jak widzimy, czas, który upłynął, wzrósł z 658 mikrosekund do zaledwie 7,25 mikrosekund. Dzieje się tak, ponieważ kiedy mówimy a = np.array([]) , wszystkie operacje są obsługiwane wewnętrznie przez numpy. A kiedy robimy a*b , numpy wewnętrznie mnoży od razu całą tablicę za pomocą wektoryzacji.

Tutaj używamy magicznego polecenia %timeit, aby określić czas wykonania procesu, który może się różnić na twoim komputerze.

Rzućmy okiem na inny przykład iloczynów zewnętrznych 2 wektorów o wymiarach (nx1) i (1xm). Wyjście będzie (nxm).

czas importu
importuj numer
importuj tablicę
a = array.array( 'i' , [losowo.randint( 1 , 100 ) for _ in range( 100 )])
b = array.array( 'i' , [losowo.randint( 1 , 100 ) for _ in range( 100 )])

T1 = czas.czas_procesu()
c = liczba.zera(( 200 , 200 ))

dla i w zakresie(len(a)):
dla j w zakresie(len(b)):
c[i][j]= a[i]*b[j]

T2 = czas.czas_procesu()

print( f”Czas obliczeń = { 1000 *(T2-T1)} ms” )

#Wyjście:
>> Czas obliczeń = 6,819299000000001 ms

Teraz zróbmy to z Numpym,

T1 = czas.czas_procesu()
c = liczba.zewnętrzny(a, b)
T2 = czas.czas_procesu()

print( f”Czas obliczeń = { 1000 *(T2-T1)} ms” )

#Wyjście:
>> Czas obliczeń = 0,2256630000001536 ms

Jak ponownie widzimy, Numpy przetwarza tę samą operację znacznie szybciej dzięki wektoryzacji.

Trzeba przeczytać: fascynujące aplikacje Pythona w prawdziwym świecie

Nadawanie

Do tej pory widzieliśmy przykłady, w których używano tablic o tym samym rozmiarze. A jeśli rozmiary tablic są różne? Tutaj pojawia się kolejna świetna funkcja Numpy, Broadcasting.

Broadcasting to kolejne rozszerzenie wektoryzacji, w którym tablice nie muszą mieć tych samych rozmiarów, aby można było na nich wykonać operacje, takie jak dodawanie, odejmowanie, mnożenie itp. Zrozummy to na bardzo prostym przykładzie dodawania tablicy i skalara.

a = np. tablica([ 1 , 1 , 1 , 1 ])
a+ 5

#Wyjście:
tablica([ 6 , 6 , 6 , 6 ])

Jak widzimy, skalar 5 został dodany do wszystkich elementów. Jak to się stało?

Aby wyobrazić sobie ten proces, możesz pomyśleć, że skalar 5 jest powtarzany 4 razy, aby utworzyć tablicę, która jest następnie dodawana do tablicy a. Pamiętaj jednak, że Numpy nie tworzy takich tablic, które zajmują tylko pamięć. Numpy po prostu „rozgłasza” lub duplikuje skalar od 5 do 4 miejsc, aby dodać go do tablicy a.

Weźmy inny prosty przykład.

a = np.jedynki(( 3 , 3 ))
b = np.jedynki( 3 )
a+b

#Wyjście:
>> tablica([[ 2. , 2. , 2. ],
[ 2. , 2. , 2. ],
[ 2. , 2. , 2. ]])

W powyższym przykładzie tablica kształtu (3,1) została rozesłana do (3,3), aby dopasować tablicę a.

Ale czy to oznacza, że ​​dowolna tablica o dowolnym wymiarze może być rozgłaszana w celu dopasowania tablicy o dowolnym wymiarze?

NIE!

Zasady nadawania

Numpy przestrzega zestawu prostych reguł, aby upewnić się, że transmitowane są tylko tablice spełniające kryteria. Spójrzmy.

Zasada nadawania mówi, że 2 macierze, które mają być obsługiwane, muszą albo mieć te same wymiary, albo jeśli któryś z nich ma 1.

Zobaczmy, jak to działa.

Przykład 1:

Rozważ poniżej tablice wymiarów:

a = 3 x 4 x 7

b = 3 x 4 x 1

Tutaj ostatni wymiar b będzie transmitowany tak, aby pasował do wymiaru a do 7.

Stąd wynik = 3 x 4 x 7

Przykład 2:

a = 3 x 4 x 7

b = 4

Teraz liczba wymiarów a i b jest nierówna. W takich przypadkach tablica z mniejszą liczbą wymiarów zostanie uzupełniona o 1.

Zatem tutaj pierwszy i ostatni wymiar b to 1, więc będą nadawane tak, aby odpowiadały wymiarom a do 3 i 7.

Stąd wynik = 3 x 4 x 7.

Przeczytaj: samouczek Pythona

Przykład 3:

a = 3 x 4 x 1 x 5

b = 3 x 1 x 7 x 1

Tutaj ponownie, drugi i ostatni wymiar b będą nadawane, aby dopasować wymiar a do 4 i 5. Również trzeci wymiar a zostanie nadany, aby dopasować wymiar b do 7.

Stąd wynik = 3 x 4 x 7 x 5

Zobaczmy teraz, kiedy warunek się nie powiedzie:

Przykład 4:

a = 3 x 4 x 7 x 5

b = 3 x 3 x 7 x 4

Tutaj drugi i czwarty wymiar b nie pasują do a i nie są równe 1. W tym przypadku Python wyrzuci błąd wartości:

ValueError: operandy nie mogły być rozgłaszane razem z kształtami ( 3 , 4 , 7 , 5 ) ( 3 , 3 , 7 , 4 )

Przykład 5:

a = 3 x 4 x 1 x 5

b = 3 x 2 x 3

Wynik: ValueError

Tutaj również drugi wymiar nie pasuje i nie jest 1 dla żadnego z nich.

Zanim pójdziesz

Zarówno wektoryzacja, jak i nadawanie są metodami, dzięki którym Numpy optymalizuje i usprawnia przetwarzanie. O tych pojęciach należy pamiętać zwłaszcza w przypadku macierzy i tablic n-wymiarowych, które są bardzo powszechne w danych obrazowych i sieciach neuronowych.

Jeśli chcesz dowiedzieć się czegoś o Pythonie, nauce o danych, sprawdź dyplom PG IIIT-B i upGrad w dziedzinie Data Science, który jest stworzony dla pracujących profesjonalistów i oferuje ponad 10 studiów przypadków i projektów, praktyczne warsztaty praktyczne, mentoring z ekspertami z branży, Indywidualnie z mentorami branżowymi, ponad 400 godzin nauki i pomocy w pracy z najlepszymi firmami.

Co to jest wektoryzacja w Pythonie?

Numpy to pakiet Pythona zapewniający kilka standardowych funkcji matematycznych umożliwiających szybkie operacje na dużych tablicach danych bez konieczności wykonywania pętli, w tym wektoryzację. Wektoryzacja służy do przyspieszania programów Pythona bez użycia pętli. Użycie takiej metody może pomóc w skróceniu czasu potrzebnego do wykonania kodu. Istnieją różne operacje wykonywane na wektorach, takie jak iloczyn skalarny wektorów, znany również jako iloczyn skalarny, ponieważ daje pojedynczy wynik, iloczyny zewnętrzne, co daje w wyniku macierz kwadratową o wymiarze równym długości x długość wektory, mnożenie elementów, które dają elementy o tych samych indeksach.

Co to jest nadawanie w Pythonie?

Słowo rozgłaszanie odnosi się do tego, jak Numpy zarządza tablicami o różnych wymiarach podczas operacji arytmetycznych, które skutkują określonymi ograniczeniami; mniejsza tablica jest transmitowana przez ogromną tablicę, aby ich formy były spójne. Transmisja umożliwia wektoryzację operacji tablicowych w taki sposób, że pętla odbywa się w C, a nie w Pythonie, jak robi to Numpy. Osiąga to bez tworzenia zbędnych kopii danych, co skutkuje wydajnymi implementacjami algorytmów. W niektórych sytuacjach rozgłaszanie jest pomysłem negatywnym, ponieważ powoduje marnotrawstwo pamięci, co spowalnia przetwarzanie.

Jakie są zastosowania NumPy w Pythonie?

NumPy lub Numerical Python to darmowa biblioteka Pythona typu open source używana przez prawie każdą branżę naukową i inżynieryjną. Biblioteka NumPy zawiera wielowymiarowe tablice i macierzowe struktury danych oraz oferuje metody wydajnego działania na tablicy, jednorodnym n-wymiarowym obiekcie tablicy. Użytkownicy mogą używać NumPy do wykonywania szerokiego zakresu operacji matematycznych na tablicach. Rozszerza Pythona o silne struktury danych, które zapewniają wydajne obliczenia za pomocą tablic i macierzy, a także ogromną bibliotekę wysokopoziomowych funkcji matematycznych, które działają na tych tablicach i macierzach.