Python NumPy Kullanımı - Nedir ve Nasıl Kullanılır?

NumPy, dizilerle çalışmak için kullanılan bir Python kütüphanesidir. Ayrıca doğrusal cebir, fourier dönüşümü ve matrisler alanında çalışmak için de gerekli işlevlere sahiptir. NumPy, 2005 yılında Travis Oliphant tarafından oluşturulmuştur. Açık kaynak kodlu bir projedir ve özgürce kullanabilirsiniz. NumPy, Numeriacal Python (Sayısal Python)’un kısaltmasıdır.

1. Neden NumPy Kullanılır?

Python’da dizilerin amacına hizmet eden listelerimiz var, ancak işlenmesi yavaştır. NumPy, geleneksel Python listelerinden 50 kata kadar daha hızlı bir dizi nesnesi sağlamayı amaçlamaktadır. NumPy’deki dizi nesnesi (array) ndarray olarak adlandırılır ve ndarray, çalışmayı çok kolaylaştıran birçok destekleyici işlev sağlar. Diziler, hız ve kaynakların çok önemli olduğu veri biliminde çok sık kullanılır.

1.1 NumPy Neden Listelerden Daha Hızlı?

NumPy bir Python kütüphanesidir ve kısmen Python’da yazılmıştır, ancak hızlı hesaplama gerektiren parçaların çoğu C veya C ++ ile yazılmıştır.

1.2 NumPy CodeBase Nerede?

NumPy’nin kaynak kodu bu github deposunda bulunmaktadır: https://github.com/numpy/numpy

2. NumPy’nin Kurulumu

Bir sistemde Python ve PIP kuruluysa NumPy’nin kurulumu çok kolaydır. Bu komutu kullanarak kurulumu yapabilirsiniz:

pip install numpy

Bu komut başarısız olursa, Anaconda, Spyder vb. Gibi zaten NumPy’nin kurulu olduğu bir python dağıtımı kullanın.

2.1 NumPy’yi Projeye Dahil Etmek

NumPy yüklendikten sonra, import anahtar sözcüğünü ekleyerek onu uygulamalarınıza dahil edebilirsiniz:

import numpy

Artık NumPy içe aktarılmıştır ve kullanıma hazırdır. Aşağıdaki kodla test edebilirsiniz.

import numpy

arr = numpy.array([1, 2, 3, 4, 5])

print(arr)

2.2 NumPy np Olarak Kullanmak

NumPy genellikle np alias (takma adı) altında içe aktarılır. alias Python’da, aynı şeye atıfta bulunmak için alternatif bir addır. İçe aktarırken as anahtar sözcüğüyle bir alias oluşturabilirsiniz.

import numpy as np

arr = np.array([1, 2, 3, 4, 5])

print(arr)

2.3 NumPy Sürümünü Kontrol Etme

Sürüm bilgisi version özniteliği altında saklanır.

print(np.__version__)

3. NumPy Dizileri Oluşturma

Bu bölümde NumPy dizilerini oluşturarak asıl bölüme giriş yapıyoruz.

3.1 NumPy ndarray Nesnesi Oluşturmak

NumPy, dizilerle çalışmak için kullanılır. NumPy’deki dizi nesnesine ndarray denir. array() işlevini kullanarak bir NumPy ndarray nesnesi oluşturabiliriz.

arr = np.array([1, 2, 3, 4, 5])

print(arr)
print(type(arr))

Bir ndarray oluşturmak için, bir listeyi, tuple’ı veya herhangi bir dizi benzeri nesneyi array() yöntemine geçirebiliriz ve bu bir ndarray‘e dönüştürülür:

arr = np.array((1, 2, 3, 4, 5))

print(arr)

3.2 Dizilerde Boyutlar

Dizilerdeki bir boyut, bir dizi derinliği düzeyidir (iç içe diziler).

3.2.1 0-D Diziler

0-D dizileri veya Skalarlar, bir dizideki öğelerdir. Bir dizideki her değer bir 0-D dizisidir.

arr = np.array(42)

print(arr)
3.2.1 1-D Diziler

Öğeleri olarak 0-D dizileri olan bir dizi, tek boyutlu veya 1-D dizi olarak adlandırılır. Bunlar en yaygın ve temel dizilerdir.

arr = np.array([1, 2, 3, 4, 5])

print(arr)
3.2.1 2-D Diziler

Öğeleri olarak 1 boyutlu dizilere sahip bir diziye 2 boyutlu dizi denir. Bunlar genellikle matris veya 2. derece tensörleri temsil etmek için kullanılır.

arr = np.array([[1, 2, 3], [4, 5, 6]])

print(arr)
3.2.1 3-D Diziler

Elemanları olarak 2 boyutlu dizilere (matrisler) sahip olan bir dizi, 3 boyutlu dizi olarak adlandırılır. Bunlar genellikle 3. dereceden bir tensörü temsil etmek için kullanılır.

arr = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]])

print(arr)

3.3 Boyut Sayısını Kontrol Etmek

NumPy Dizileri, dizinin kaç boyuta sahip olduğunu bize söyleyen bir tamsayı döndüren ndim niteliğini sağlar. Dizilerin kaç boyuta sahip olduğunu kontrol etmek için ndim kullanabiliriz:

a = np.array(42)
b = np.array([1, 2, 3, 4, 5])
c = np.array([[1, 2, 3], [4, 5, 6]])
d = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]])

print(a.ndim)  # 0
print(b.ndim)  # 1
print(c.ndim)  # 2
print(d.ndim)  # 3

3.5 Daha Yüksek Boyutlu Diziler

Bir dizi herhangi bir sayıda boyuta sahip olabilir. Dizi oluşturulduğunda, ndmin bağımsız değişkenini kullanarak boyutların sayısını tanımlayabilirsiniz. Örneğin 5 boyutlu bir dizi oluşturmak için aşağıdaki kullanıma bakabilirsiniz:

arr = np.array([1, 2, 3, 4], ndmin=5)

print(arr)                         # [[[[[1 2 3 4]]]]]
print('Boyut sayısı:', arr.ndim)   # 5

Bu dizide en içteki boyut (5. boyut) 4 öğeye, 4. boyut vektör olan 1 öğeye, 3. boyut vektörün bulunduğu matris olan 1 öğeye, 2. boyutun ise 3 boyutlu dizi olan 1 öğesi ve 1. dim, 4D dizisi olan 1 öğeye sahiptir.

4. NumPy Dizi İndeksleme

Dizi elemanlarına ulaşabilmek ve onlarla çalışabilmek için indexleri kullanmalıyız.

4.1 Dizi Öğelerine Erişim

Dizi indeksleme, bir dizi öğesine erişimle aynıdır. Bir dizi öğesine, dizin numarasına başvurarak erişebilirsiniz. NumPy dizilerindeki indexler 0 ile başlar, yani bu, ilk öğenin indexi 0’a ve ikincinin indexi 1’e sahip olduğu anlamına gelir.

Aşağıdaki örnek, diziden ilk öğeyi alır:

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

print(arr[0])  # 1

Aşağıdaki örnek, diziden ikinci öğeyi alır:

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

print(arr[1])  # 2

4.2 2 Boyutlu Dizilere Erişim

2 boyutlu dizilerden öğelere erişmek için, öğenin boyutunu ve dizinini temsil eden virgülle ayrılmış tamsayılar kullanabiliriz.

arr = np.array([[1,2,3,4,5], [6,7,8,9,10]])

print('1. boyuttaki 2.eleman: ', arr[0, 1])

4.3 3 Boyutlu Dizilere Erişim

3 boyutlu dizilerden öğelere erişmek için, öğenin boyutlarını ve dizinini temsil eden virgülle ayrılmış tamsayılar kullanabiliriz.

arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])

print(arr[0, 1, 2])

4.4 Negatif İndeksleme

Bir diziye sondan erişmek için negatif indeksleme kullanabilirsiniz. Örneğin, 2. boyuttan son öğeyi yazdırmak için:

arr = np.array([[1,2,3,4,5], [6,7,8,9,10]])

print('Last element from 2nd dim: ', arr[1, -1])

5. NumPy Dizi Dilimleme

NumPy ile elinizdeki dizileri dilimleyebilir ve yeni diziler elde edebilirsiniz.

5.1 Dizileri dilimleme

Python’da dilimleme, belirli bir dizinden belirli bir dizine öğe almak anlamına gelir.

İndeks yerine dilimi şu şekilde geçiririz: [start: end]. Ayrıca adımı şu şekilde tanımlayabiliriz: [start: end: step].

Aşağıdaki diziden index 1’den index 5’e öğeleri dilimlemek için:

arr = np.array([1, 2, 3, 4, 5, 6, 7])

print(arr[1:5])   # [2 3 4 5]

Not: Sonuç, başlangıç indexini içerir, ancak bitiş indexini hariç tutar.

Öğeleri index 4’ten dizinin sonuna kadar dilimlemek için:

arr = np.array([1, 2, 3, 4, 5, 6, 7])

print(arr[4:])   # [5 6 7]

Öğeleri baştan 4. indexe kadar dilimleyin:

arr = np.array([1, 2, 3, 4, 5, 6, 7])

print(arr[:4])   # [1 2 3 4]

5.2 Negatif Dilimleme

Sondan bir indexe başvurmak için eksi operatörünü kullanılır. Örneğin sondan 3. indexten sondan 1. indexe kadar dilimlemek için şunu kullanabiliriz:

arr = np.array([1, 2, 3, 4, 5, 6, 7])

print(arr[-3:-1])   # [5 6]

5.3 STEP

Dilimleme adımını belirlemek için step değerini kullanınız. Örneğin index 1’den index 5’e diğer kadar her 2 ögeden birini döndürür:

arr = np.array([1, 2, 3, 4, 5, 6, 7])

print(arr[1:5:2])   # [2 4]

Dizinin tamamındaki her 2. ögeden birini döndürür:

arr = np.array([1, 2, 3, 4, 5, 6, 7])

print(arr[::2])   # [1 3 5 7]

5.4 Boyutlu Dizileri Dilimleme

İkinci öğeden, öğeleri index 1’den index 4’e kadar dilimlemek için aşağıdaki kodu kullanabilirsiniz:

arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])

print(arr[1, 1:4])   # [7 8 9]

Her iki öğeden, index 2’yi döndür:

arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])

print(arr[0:2, 2])   # [3 8]

6. NumPy’de Veri Türleri

NumPy’nin bazı ekstra veri türleri vardır ve tamsayılar için i, işaretsiz tamsayılar için u vb. gibi tek karakterli veri türlerine atıfta bulunur. Aşağıda NumPy’deki tüm veri türlerinin ve bunları temsil etmek için kullanılan karakterlerin bir listesi bulunmaktadır.

  • i – integer
  • b – boolean
  • u – unsigned integer
  • f – float
  • c – complex float
  • m – timedelta
  • M – datetime
  • O – object
  • S – string
  • U – unicode string
  • V – fixed chunk of memory for other type ( void )

6.1 Bir Dizinin Veri Türünü Kontrol Etme

NumPy dizi nesnesi, dizinin veri türünü döndüren dtype adında bir özelliğe sahiptir:

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

print(arr.dtype) # int64

İndexleri içeren bir dizinin veri türünü almak için:

arr = np.array(['apple', 'banana', 'cherry'])

print(arr.dtype) # <U6

6.2 Tanımlı Veri Türüne Sahip Diziler Oluşturma

Diziler oluşturmak için array() işlevini kullanırız ve bu işlev isteğe bağlı bir argüman alabilir: dtype, dizi öğelerinin beklenen veri türünü tanımlamamıza izin verir. Örneğin veri türü dizesiyle bir dizi oluşturmak için:

arr = np.array([1, 2, 3, 4], dtype='S')

print(arr)        # [b'1' b'2' b'3' b'4']
print(arr.dtype)  # |S1

iuf,S ve U için boyutu da tanımlayabiliriz. Örneğin veri türü 4 bayt tamsayı ile bir dizi oluşturmak için:

arr = np.array([1, 2, 3, 4], dtype='i4')

print(arr)        # [1 2 3 4]
print(arr.dtype)  # int32

6.3 Ya Bir Değer Dönüştürülemezse?

Elemanların dönüştürülemeyeceği bir tür verilirse, NumPy bir ValueError oluşturacaktır. ValueError: Python’da bir işleve iletilen bağımsız değişken türü beklenmedik / yanlış olduğunda ortaya çıkar. Örneğin 'a' gibi tamsayı olmayan bir dizge tam sayıya dönüştürülemez (bir hataya neden olur):

arr = np.array(['a', '2', '3'], dtype='i')

6.4 Mevcut Dizilerdeki Veri Türünü Dönüştürme

Mevcut bir dizinin veri türünü değiştirmenin en iyi yolu, dizinin astype() yöntemiyle bir kopyasını oluşturmaktır. astype() işlevi, dizinin bir kopyasını oluşturur ve veri türünü bir parametre olarak belirtmenize olanak tanır. Veri türü, float için 'f', tamsayı için 'i' vb. gibi bir dize kullanılarak belirtilebilir veya veri türünü float için float ve tamsayı için int gibi doğrudan kullanabilirsiniz.

Örneğin parametre değeri olarak ‘i’ kullanarak veri türünü float’tan tamsayıya değiştirebiliriz:

arr = np.array([1.1, 2.1, 3.1])

newarr = arr.astype('i')

print(newarr)        # [1 2 3]
print(newarr.dtype)  # int32

Parametre değeri olarak int kullanarak veri türünü float’tan tamsayıya değiştirebiliriz:

arr = np.array([1.1, 2.1, 3.1])

newarr = arr.astype(int)

print(newarr)        # [1 2 3]
print(newarr.dtype)  # int64

Veri türünü tam sayıdan mantıksal değere değiştirebiliriz:

arr = np.array([1, 0, 3])

newarr = arr.astype(bool)

print(newarr)        # [ True False True]
print(newarr.dtype)  # bool

7. NumPy Dizi Kopya (Copy) ve Görünüm (View)

Bir dizinin kopyası ile görünümüm arasındaki temel fark, kopyanın yeni bir dizi olması ve görünümün yalnızca orijinal dizinin bir görünümü olmasıdır.

Kopya verinin sahibidir ve kopyada yapılan herhangi bir değişiklik orijinal diziyi etkilemeyecektir ve orijinal dizide yapılan herhangi bir değişiklik kopyayı etkilemeyecektir.

Görünüm verilere sahip değildir ve görünümde yapılan herhangi bir değişiklik orijinal diziyi etkiler ve orijinal dizide yapılan herhangi bir değişiklik görünümü etkiler.

7.1 COPY

Bir kopya oluşturalım, orijinal diziyi değiştirelim ve her iki diziyi de görüntüleyelim:

arr = np.array([1, 2, 3, 4, 5])
x = arr.copy()
arr[0] = 42

print(arr)  # [42  2  3  4  5]
print(x)    # [1, 2, 3, 4, 5]

Kopya (Copy), orijinal dizide yapılan değişikliklerden etkilenmemektedir.

7.2 VİEW

Bir görünüm oluşturalım, orijinal diziyi değiştirelim ve her iki diziyi de görüntüleyelim:

arr = np.array([1, 2, 3, 4, 5])
x = arr.view()
arr[0] = 42

print(arr)  # [42  2  3  4  5]
print(x)    # [42  2  3  4  5]

Görünüm (View), orijinal dizide yapılan değişikliklerden ETKİLENMELİDİR.

7.3 Dizinin Kendi Verisine Sahip Olup Olmadığını Kontrol Etmek

Yukarıda belirtildiği gibi, kopyalar verinin sahibidir ve görünümler verinin sahibi değildir, ancak bunu nasıl kontrol edebiliriz?

Her NumPy dizisi, dizinin kendi verilerine sahip olması durumunda None döndüren base özelliğine sahiptir. Diğer bir deyişle, base nitelik orijinal nesneye atıfta bulunur.

arr = np.array([1, 2, 3, 4, 5])

x = arr.copy()
y = arr.view()

print(x.base)  # None
print(y.base)  # [1, 2, 3, 4, 5]

Özetle Kopya None değerini döndürür. Görünüm, orijinal diziyi döndürür.

8. NumPy Dizi Şekli (Shape)

Bir dizinin şekli (shape), her boyuttaki öğelerin sayısıdır.

8.1 Bir Dizinin Şeklini Almak

NumPy dizileri, her indexe karşılık gelen öğelerin sayısına sahip bir tuple döndüren shape adlı bir özniteliğe sahiptir. 2 boyutlu bir dizinin şeklini yazdıralım:

arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])

print(arr.shape)  # (2, 4)

Yukarıdaki örnek (2, 4) değerini döndürür; bu, dizinin 2 boyuta sahip olduğu ve her boyutun 4 öğeye sahip olduğu anlamına gelir.

1,2,3,4 değerlerine sahip bir vektörü ndmin kullanarak 5 boyutlu bir dizi şeklinde oluşturan ve son boyutun 4 değerine sahip olduğunu doğrulayan örnek bir kod yazalım:

arr = np.array([1, 2, 3, 4], ndmin=5)

print(arr)
print('shape: ', arr.shape)   # (1, 1, 1, 1, 4)

8.2 Shape demeti neyi temsil eder?

Her dizindeki tamsayılar, karşılık gelen boyutun sahip olduğu öğelerin sayısını söyler. Yukarıdaki indeks-4’te 4 değerine sahibiz, bu nedenle 5. (4 + 1.) boyutun 4 öğesi olduğunu söyleyebiliriz.

9. NumPy Dizi Yeniden Şekillendirme (Reshaping)

Yeniden şekillendirme, bir dizinin şeklini değiştirmek anlamına gelir. Bir dizinin şekli, her boyuttaki öğelerin sayısıdır. Yeniden şekillendirerek boyutları ekleyebilir, kaldırabilir veya her boyuttaki öğe sayısını değiştirebiliriz.

9.1 1-D’den 2-D’ye Reshape

Aşağıdaki 1 boyutlu diziyi 12 öğeli bir 2 boyutlu diziye dönüştürelim:

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])

newarr = arr.reshape(4, 3)

print(newarr)

# [[ 1  2  3]
# [ 4  5  6]
# [ 7  8  9]
# [10 11 12]]

9.2 1-D’den 3-D’ye Reshape

Aşağıdaki 1-D diziyi 12 elemanlı bir 3-D dizisine dönüştürelim. En dıştaki boyut, her biri 2 öğe içeren 3 dizi içeren 2 diziye sahip olacaktır:

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])

newarr = arr.reshape(2, 3, 2)

print(newarr)

# [[[ 1  2]
#  [ 3  4]
#  [ 5  6]]

# [[ 7  8]
#  [ 9 10]
#  [11 12]]]

9.3 Herhangi bir Şekle Yeniden Şekillendirebilir miyiz?

Evet, yeniden şekillendirme için gerekli öğeler her iki şekilde de eşit olduğu sürece reshape yapabiliriz. 8 öğeli bir 1D dizisini 2 satırlı 2D dizide 4 öğeye yeniden şekillendirebiliriz, ancak 3×3 = 9 öğe gerektireceği için onu 3 öğeli 3 satırlı 2D diziye yeniden şekillendiremeyiz.

8 öğeli 1D diziyi, her boyutta 3 öğeli bir 2D diziye dönüştürmeyi deneyelim (bir hataya neden olur):

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
newarr = arr.reshape(3, 3)

print(newarr)  # ValueError: cannot reshape array of size 8 into shape (3,3)

9.4 Shape ve Reshape’in Copy veya View Olduğunu Anlamak

Şekillendirilen dizinin bir kopya mı yoksa bir görünüm mü olduğunu kontrol edebiliriz:

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])

print(arr.reshape(2, 4).base)  # [1 2 3 4 5 6 7 8]

Yukarıdaki örnek, orijinal diziyi döndürür, bu nedenle bir (view) görünümdür.

9.5 Bilinmeyen Boyut

Bir “bilinmeyen” (unkown) boyuta sahip olmanıza izin verilir. Bu, yeniden şekillendirme yönteminde boyutlardan biri için tam bir sayı belirtmeniz gerekmediği anlamına gelir. Değer olarak -1‘i geçirin ve NumPy bu sayıyı sizin için hesaplayacaktır. Örneğin 8 öğeli 1D diziyi 2×2 öğeli 3D diziye dönüştürelim:

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])

newarr = arr.reshape(2, 2, -1)

print(newarr)

# [[[1 2]
#  [3 4]]
#
# [[5 6]
#  [7 8]]]

NOT: -1‘i birden fazla boyuta geçiremeyiz.

9.6 Dizileri Düzleştirme (Flatten)

Düzleştirme dizisi, çok boyutlu bir diziyi 1 boyutlu bir diziye dönüştürmek anlamına gelir. Bunu yapmak için reshape(-1) kullanabiliriz.

arr = np.array([[1, 2, 3], [4, 5, 6]])

newarr = arr.reshape(-1)

print(newarr)  # [1 2 3 4 5 6]

NOT: Numpyd dizilerinin şekillerini flatten ve ravel‘de değiştirebilmek ve ayrıca rot90flipfliplrflipud vb. fonksiyonlarla yeniden düzenlenmek gibi birçok işlev mevcuttur. Bunları da ayrı bir kaynaktan inceleyebilirsiniz.

10. NumPy Dizileri Yineleme (Iterating)

Yineleme (Iterating), öğeleri tek tek gözden geçirmek anlamına gelir. Numpy’deki çok boyutlu dizilerle uğraşırken, bunu python döngüsünün temel for döngüsünü kullanarak yapabiliriz. Tek boyutlu bir dizi üzerinde yinelersek, her bir öğeden birer birer geçecektir.

Aşağıdaki 1 boyutlu dizinin öğeleri üzerinde yineleme işlemi yapalım:

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

for x in arr:
  print(x)

# 1
# 2
# 3

10.1 2 Boyutlu Dizileri Yineleme

2 boyutlu bir dizide yineleme ile tüm satırlardan geçebiliriz. Aşağıdaki 2 boyutlu dizinin öğeleri üzerinde yineleme yapalım:

arr = np.array([[1, 2, 3], [4, 5, 6]])

for x in arr:
  print(x)

# [1, 2, 3]
# [4, 5, 6]

Bir n-D dizisi üzerinde yinelersek, tek tek n-1. Boyuttan geçecektir.

Gerçek değerleri, skalerleri döndürmek için, her boyuttaki dizileri yinelemeliyiz. 2-B dizisinin her bir skaler öğesi üzerinde yineleyelim:

arr = np.array([[1, 2], [4, 5]])

for x in arr:
  for y in x:
    print(y)

# 1
# 2
# 3
# 4

10.2 3 Boyutlu Dizileri Yineleme

3 boyutlu bir dizide, tüm 2 boyutlu dizilerden geçecektir. Aşağıdaki 3 boyutlu dizinin öğeleri üzerinde yineleyelim:

arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])

for x in arr:
  print(x)

# [[1 2 3]
#  [4 5 6]]
# [[ 7  8  9]
#  [10 11 12]]

Gerçek değerleri, skalerleri döndürmek için, her boyuttaki dizileri yinelemeliyiz.

import numpy as np

arr = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])

for x in arr:
  for y in x:
    for z in y:
      print(z)

# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8

10.3 Nditer() Kullanarak Dizileri Yineleme

nditer() işlevi, çok temelden çok ileri düzey yinelemelere kadar kullanılabilen bir yardımcı işlevdir. Yinelemede karşılaştığımız bazı temel sorunları çözer. Hemen örneklerle üzerinden geçelim.

10.3.1 Her Skaler Eleman Üzerinde Yineleme

for döngülerinde, bir dizinin her skaleri için n adet for döngüsü kullanmamız gerekir ki bu da çok yüksek boyutsallığa sahip diziler için yazmayı zorlaştırır. Fakat nditer() kullanarak bu işlemi basitçe gerçekleştirebiliriz. Örnek olarak aşağıdaki 3 boyutlu diziyi yineleyelim:

arr = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])

for x in np.nditer(arr):
  print(x)

# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
10.3.2 Farklı Veri Türleriyle Dizi Yineleme

op_dtypes argümanını kullanarak yineleme sırasında öğelerin veri türünü değiştirmek için beklenen veri türünü iletebiliriz.

NumPy, in-place veri türünü (öğenin dizide olduğu yerde) değiştirmez, bu nedenle bu eylemi gerçekleştirmek için başka bir alana ihtiyaç duyar, bu fazladan boşluğa tampon adı verilir ve onu nditer() içinde etkinleştirmek için flags=['buffered'] parametresini kullanabiliriz.

Dizi boyunca bir string olarak yineleme yapalım:

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

for x in np.nditer(arr, flags=['buffered'], op_dtypes=['S']):
  print(x)

# b'1'
# b'2'
# b'3'

10.4 Farklı Adım Boyutuyla Yineleme

Adım boyutu ayarlayabilmek için önce filtrelemeyi ve ardından yinelemeyi kullanabiliriz. Örneğin birer öğeyi atlayarak 2D dizinin her skaler öğesini yineleyelim

arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])

for x in np.nditer(arr[:, ::2]):
  print(x)

# 1
# 3
# 5
# 7

10.5 Ndenumerate() Kullanarak Numaralandırılmış Yineleme

Numaralandırma (numerate), bir şeylerin sıra numaralarının tek tek belirtilmesi anlamına gelir. Bazen yineleme sırasında öğenin karşılık gelen indeksine ihtiyaç duyarız, bu kullanım durumları için ndenumerate() yöntemi kullanılabilir. Örneğin aşağıdaki 1D dizi öğelerini numaralandıralım:

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

for idx, x in np.ndenumerate(arr):
  print(idx, x)

# (0,) 1
# (1,) 2
# (2,) 3

Aşağıdaki 2B dizinin öğelerini numaralandıralım:

import numpy as np

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

for idx, x in np.ndenumerate(arr):
  print(idx, x)

# (0, 0) 1
# (0, 1) 2
# (1, 0) 3
# (1, 1) 4

11. NumPy Dizilerini Birleştirme (Join)

Birleştirme (Joining), iki veya daha fazla dizinin içeriğini tek bir diziye koymak anlamına gelir. SQL’de tabloları bir anahtara dayalı olarak birleştiririz, NumPy’de ise dizileri eksenlere göre birleştirebiliriz. Boyutla birlikte concatenate() işlevine birleştirmek istediğimiz bir dizi diziyi iletiriz. Boyut açıkça geçirilmezse 0 olarak alınır.

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])

arr = np.concatenate((arr1, arr2))

print(arr)

# [1 2 3 4 5 6]

iki 2 boyutlu diziyi birleştirelim (axis = 1):

arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])

arr = np.concatenate((arr1, arr2), axis=1)

print(arr)

# [[1 2 5 6]
#  [3 4 7 8]]

11.1 Yığın (Stack) İşlevlerini Kullanarak Dizileri Birleştirme

Yığınlama (Stack), birleştirme ile aynıdır ama tek farkı, yığınlamanın yeni bir eksen boyunca yapılmasıdır. İkinci eksen boyunca iki 1-D dizisini birleştirebiliriz, bu da onları diğerinin üzerine koymaya neden olur, yani yığınlama yapmış oluruz.

Axis birlikte stack() yöntemine birleştirmek istediğimiz bir dizi diziyi iletiriz. Axis açıkça geçirilmezse 0 olarak alınır.

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])

arr = np.stack((arr1, arr2), axis=1)

print(arr)

# [[1 4]
#  [2 5]
#  [3 6]]

11.2 Satırlar Boyunca İstifleme

NumPy, satırlar boyunca yığınlamak için hstack() yardımcı işlevini kullanır.

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])

arr = np.hstack((arr1, arr2))

print(arr)

# [1 2 3 4 5 6]

11.3 Sütunlar Boyunca İstifleme

NumPy, sütunlar boyunca yığınlamak için vstack() yardımcı işlevini kullanır.

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])

arr = np.vstack((arr1, arr2))

print(arr)

# [[1 2 3]
#  [4 5 6]]

11.4 Yükseklik Boyunca İstifleme (derinlik)

NumPy, derinlikle aynı yükseklik boyunca yığınlamak için dstack() yardımcı işlevini kullanır.

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])

arr = np.dstack((arr1, arr2))

print(arr)

# [[[1 4]
#   [2 5]
#   [3 6]]]

12. NumPy Dizilerini Bölme (Split)

Bölme veya parçalama (split), birleştirme işleminin tersi işlemidir. Birleştirme, birden çok diziyi tek bir dizide birleştirirken bölme, bir diziyi birden çok diziye böler. Dizileri bölmek için array_split() kullanırız ve bölmek istediğimiz dizi ile bölme sayısını iletiriz.

Örnekteki diziyi 3 bölüme ayıralım:

arr = np.array([1, 2, 3, 4, 5, 6])

newarr = np.array_split(arr, 3)

print(newarr)

# [array([1, 2]), array([3, 4]), array([5, 6])]

Not: Dönüş değeri, üç dizi içeren bir dizidir.

Dizi, gerekenden daha az öğeye sahipse, sondan buna göre ayarlanacaktır.

arr = np.array([1, 2, 3, 4, 5, 6])

newarr = np.array_split(arr, 4)

print(newarr)

# [array([1, 2]), array([3, 4]), array([5]), array([6])]

Not: Ayrıca split() yöntemine sahibiz, ancak yukarıdaki örnekte olduğu gibi bölme için kaynak dizisindeki öğeler daha az olduğunda öğeleri ayarlayamaz. array_split() düzgün örnekteki gibi çalışırken ancak split() başarısız olur.

12.1 2 Boyutlu Dizileri Bölme

2 boyutlu dizileri bölerken aynı fonksiyonu kullanabiliriz. Array_split() yöntemini kullanarak, bölmek istediğiniz diziyi ve yapmak istediğiniz bölme sayısını iletebilirsiniz. Örneğin 2 boyutlu diziyi üç 2 boyutlu diziye bölelim:

arr = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])

newarr = np.array_split(arr, 3)

print(newarr)

# [array([[1, 2], [3, 4]]), 
#  array([[5, 6], [7, 8]]), 
#     array([[9, 10], [11, 12]])]

Yukarıdaki örnek, üç adet 2 boyutlu dizi döndürür. Ek olarak, ayırma işlemini hangi axis ile yapmak istediğinizi de belirleyebilirsiniz. Aşağıdaki örnek üç adet 2 boyutlu dizi döndürür, ancak bunlar sıra boyunca bölünmüştür (axis = 1).

arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [16, 17, 18]])

newarr = np.array_split(arr, 3, axis=1)

print(newarr)

# [array([[1], [4], [7], [10], [13], [16]]), 
#  array([[2], [5], [8], [11], [14], [17]]), 
#  array([[3], [6], [9], [12], [15], [18]])]

Alternatif bir çözüm olarak, hstack() yerine hsplit() kullanılmaktadır. Örneğin 2-D dizisini satırlar boyunca üç 2-D diziye bölmek için hsplit() yöntemini kullanalım.

arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [16, 17, 18]])

newarr = np.hsplit(arr, 3)

print(newarr)

# [array([[1], [4], [7], [10], [13], [16]]), 
#  array([[2], [5], [8], [11], [14], [17]]), 
#  array([[3], [6], [9], [12], [15], [18]])]

Not: vstack() ve dstack() için benzer alternatifler vsplit() ve dsplit() olarak mevcuttur.

13. NumPy Dizilerde Arama

Bir dizide belirli bir değer arayabilir ve eşleşme sağlayan dizinleri döndürebilirsiniz. Bir dizide arama yapabilmek için where() yöntemini kullanırız. Örneğin değerin 4 olduğu indexleri bulalım:

arr = np.array([1, 2, 3, 4, 5, 4, 4])

x = np.where(arr == 4)

print(x)   # (array([3, 5, 6]),)

Yukarıdaki örnek bir demet döndürecektir. Bu, 4 değerinin index 3, 5 ve 6’da mevcut olduğu anlamına gelir. Şimdide değerlerin çift olduğu indexleri bulalım:

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])

x = np.where(arr%2 == 0)

print(x)   # (array([1, 3, 5, 7]),)

13.1 Sıralanmış Arama (Sorted Search)

Dizide ikili arama yapan ve arama sırasını korumak için belirtilen değerin ekleneceği indexi döndüren searchsorted() adında bir yöntem vardır. searchsorted() yönteminin sıralanmış (sorted) dizilerde kullanıldığı varsayılır. Örneğin 4 değerinin eklenmesi gereken indexi bulun:

arr = np.array([1, 3, 5, 7, 9])

x = np.searchsorted(arr, 4)

print(x)   # 2

Sıralama düzenini korumak için 4 sayısı index 2’ye eklenmelidir. Yöntem, aramayı soldan başlatır ve 4 sayısının artık bir sonraki değerden daha büyük olmadığı ilk indexi döndürür. Daha iyi anlayabilmek için diziyi bozalım:

arr = np.array([1, 3, 5, 3, 1, 7, 9])

x = np.searchsorted(arr, 4)

print(x)   # 5

Burada 2.indexten sonra 4 ten daha küçük bir değer geldiği için aramaya devam ediyor ve artık bir sonraki değer kendinden büyük olmadığı ilk indexi döndürüyor. Son olarak ise aşağıdaki örnek ile oldukça açıklayıcı olacaktır.

arr = np.array([1, 3, 5, 6, 1, 7, 9])

x = np.searchsorted(arr, 4)

print(x)   # 2

13.1.1 Sağdan Başlayarak Arama

Varsayılan olarak en soldaki index döndürülür, ancak bunun yerine en sağdaki indexi döndürmek için side = 'right' parametresini verebiliriz. Örneğin sağdan başlayarak 7 değerinin eklenmesi gereken indexi bulalım:

arr = np.array([6, 7, 8, 9])

x = np.searchsorted(arr, 7, side='right')

print(x)   # 2

Sıralama düzenini korumak için index 2’ye 7 sayısı eklenmelidir. Yöntem, aramayı sağdan başlatır ve 7 sayısının artık bir sonraki değerden daha az olmadığı ilk indexi döndürür.

13.1.2 Çoklu Değerler

Birden fazla değer aramak için, belirtilen değerlere sahip bir dizi kullanabiliriz. Örneğin 2, 4 ve 6 değerlerinin eklenmesi gereken indexleri bulalım:

arr = np.array([1, 3, 5, 7])

x = np.searchsorted(arr, [2, 4, 6])

print(x)   # [1 2 3]

Dönüş değeri, sırayı korumak için orijinal diziye 2, 4, 6’nın ekleneceği üç indexi içeren bir dizidir: [1 2 3].

14. NumPy Dizileri Sıralama (Sorting)

Sıralama (sorting), öğeleri sıralı bir sıraya koymak anlamına gelir. Sıralama, sayısal veya alfabetik, artan veya azalan gibi öğelere karşılık gelen bir sıraya sahip herhangi bir sıradır. NumPy ndarray nesnesi, belirli bir diziyi sıralayacak sort() adında bir işleve sahiptir.

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

print(np.sort(arr))   # [0 1 2 3]

Not: Bu yöntem, orjinal diziyi değiştirmeden bırakarak dizinin bir kopyasını döndürür.

Ayrıca string dizilerini veya başka herhangi bir veri türünü sıralayabilirsiniz:

String dizilerini alfabetik olarak sıralar.

arr = np.array(['banana', 'cherry', 'apple'])

print(np.sort(arr))   # ['apple' 'banana' 'cherry']

Boolean dizileri 0/1 durumuna göre sıralar.

arr = np.array([True, False, True])

print(np.sort(arr))  [False True True]

14.1 2 Boyutlu Bir Diziyi Sıralama

2 boyutlu bir dizide sort() yöntemini kullanırsanız, her iki dizi de sıralanır:

arr = np.array([[3, 2, 4], [5, 0, 1]])

print(np.sort(arr))   # [[2 3 4] [0 1 5]]

15. NumPy Dizileri Filtreleme

Var olan bir diziden bazı öğeleri elde etmek ve bunlardan yeni bir dizi oluşturmak filtreleme olarak adlandırılır.

Bir boolean index listesi, dizideki indexlere karşılık gelen mantıksal değerlerin bir listesidir. Bir indexteki değer True ise, bu öğe filtrelenmiş dizide yer alır, bu dizindeki değer False ise bu öğe filtrelenmiş diziden hariç tutulur. Örnek olarak index 0 ve 2’deki öğelerden bir dizi oluşturun:

arr = np.array([41, 42, 43, 44])

x = [True, False, True, False]

newarr = arr[x]

print(newarr)   # [41 43]

Yukarıdaki örnek [41, 43] döndürür, peki neden? Çünkü yeni filtre yalnızca filtre dizisinin True değerine sahip olduğu değerleri içerdiğinden, bu durumda dizin 0 ve 2’dir.

15.1 Filtre Dizisinin Oluşturulması

Yukarıdaki örnekte True ve False değerlerini sabit kodladık, ancak genel kullanım, koşullara dayalı bir filtre dizisi oluşturmaktır. Örnek olarak yalnızca 42’den büyük değerleri döndürecek bir filtre dizisi oluşturun:

arr = np.array([41, 42, 43, 44])

# Create an empty list
filter_arr = []

# go through each element in arr
for element in arr:
  # if the element is higher than 42, set the value to True, otherwise False:
  if element > 42:
    filter_arr.append(True)
  else:
    filter_arr.append(False)

newarr = arr[filter_arr]

print(filter_arr)   # [False, False, True, True]
print(newarr)       # [43 44]

Başka bir örnek olarak orjinal diziden yalnızca çift sayıları döndürecek bir filtre dizisi oluşturalım:

arr = np.array([1, 2, 3, 4, 5, 6, 7])

# Create an empty list
filter_arr = []

# go through each element in arr
for element in arr:
  # if the element is completely divisble by 2, set the value to True, otherwise False
  if element % 2 == 0:
    filter_arr.append(True)
  else:
    filter_arr.append(False)

newarr = arr[filter_arr]

print(filter_arr)   # [False, True, False, True, False, True, False]
print(newarr)       # [2 4 6]

15.2 Doğrudan Diziden Filtre Oluşturma

Yukarıdaki örnek, NumPy’de oldukça yaygın bir görevdir ve NumPy, bunun üstesinden gelmek için güzel bir yol sağlar. Durumumuzda yinelenebilir değişken yerine diziyi doğrudan değiştirebiliriz ve tam da beklediğimiz gibi çalışacaktır. Aynı yukarıdaki örnekteki gibi yalnızca 42’den büyük değerleri döndürecek bir filtre dizisi oluşturalım:

arr = np.array([41, 42, 43, 44])

filter_arr = arr > 42

newarr = arr[filter_arr]

print(filter_arr)   # [False False  True  True]
print(newarr)       # [43 44]

Orijinal diziden yalnızca çift sayıları döndürecek bir filtre dizisi oluşturalım:

arr = np.array([1, 2, 3, 4, 5, 6, 7])

filter_arr = arr % 2 == 0

newarr = arr[filter_arr]

print(filter_arr)   # [False  True False  True False  True False]
print(newarr)       # [2 4 6]

16. NumPy’de Rastgele (Random) Sayılar

Rastgele sayı, her seferinde farklı bir sayı demek DEĞİLDİR. Rastgele, mantıksal olarak tahmin edilemeyen bir şey anlamına gelir.

16.1 Sözde Rastgele ve Gerçek Rastgele.

Bilgisayarlar programlar üzerinde çalışır ve programlar kesin talimatlar dizisidir. Bu, rastgele bir sayı oluşturmak için bir algoritma olması gerektiği anlamına da gelir. Rastgele sayı üreten bir program varsa, tahmin edilebilir, bu nedenle gerçekten rastgele değildir.

Bir üretim algoritması aracılığıyla üretilen rastgele sayılara sözde rastgele (pseudo random) denir. Peki gerçekten rastgele sayılar üretebilir miyiz?

Evet. Bilgisayarlarımızda gerçekten rastgele bir sayı oluşturmak için, rastgele verileri bazı dış kaynaklardan almamız gerekir. Bu dış kaynak genellikle tuş vuruşlarımız, fare hareketlerimiz, ağdaki verilerimiz vb. olabilir.

Güvenlikle ilgili olmadığı sürece (ör. Şifreleme anahtarları) veya uygulamanın temeli rastgelelik (ör. Dijital rulet çarkları) olmadığı sürece gerçekten rastgele sayılara ihtiyacımız yoktur. Bu nedenle eğitimde sözde rasgele sayılar kullanacağız.

16.1 Rastgele Integer Sayı Oluştur

NumPy random modülü rastgele sayılarla çalışmasını sağlar. Örneğin 0 ile 100 arasında rastgele bir tamsayı oluşturalım:

from numpy import random

x = random.randint(100)

print(x)

16.2 Rastgele Float Sayı Oluşturmak

Rastgele modülün rand() yöntemi, 0 ile 1 arasında rastgele bir float değer döndürür.

from numpy import random

x = random.rand()

print(x)

16.3 Rastgele Dizi Oluşturmak

NumPy’de dizilerle çalışıyoruz ve rasgele diziler üretmek istiyorsanız yukarıdaki örneklerden iki yöntemi de kullanabilirsiniz.

16.3.1 Integer Dizi

randint() yöntemi, bir dizinin size değerimi belirtebileceğiniz bir boyut parametresi alır. Örneğin 0’dan 100’e kadar 5 rastgele tam sayı içeren bir 1-D dizisi oluşturalım:

x=random.randint(100, size=(5))

print(x)

Her satır 0’dan 100’e kadar 5 rastgele tam sayı içeren 3 satırlı 2 boyutlu bir dizi oluşturalım:

x = random.randint(100, size=(3, 5))

print(x)
16.3.2 Integer Dizi

rand() yöntemi ayrıca dizinin şeklini belirtmenize de izin verir. Örneğin 5 rastgele float sayı içeren 1 boyutlu bir dizi oluşturalım:

x = random.rand(5)

print(x)

Her satırda 5 rastgele sayı içeren 3 satırlı 2 boyutlu bir dizi oluşturalım:

x = random.rand(3, 5)

print(x)

16.4 Diziden Rastgele Sayı Oluşturmak

choice() yöntemi, elimizdeki bir dizi elemanlarından rastgele bir değer oluşturmanıza olanak tanır. choice() yöntemi, parametre olarak bir diziyi alır ve değerlerden birini rastgele döndürür.

x = random.choice([3, 5, 7, 9])

print(x)

choice() yöntemi değer olarak bir dizi döndürmenize de izin verir. Dizinin şeklini belirtmek için bir size parametresi eklemeliyiz. Örneğin dizi parametresindeki (3, 5, 7 ve 9) değerlerden oluşan 2 boyutlu bir dizi oluşturalım:

x = random.choice([3, 5, 7, 9], size=(3, 5))

print(x)

17. NumPy Evrensel Fonksiyonlar (ufuncs)

ufuncs, Universal Functions (Evrensel İşlevler) anlamına gelir ve bunlar, ndarray nesnesi üzerinde çalışan NumPy işlevleridir.

17.1 Neden ufuncs Kullanırız?

ufunc’lar NumPy’de vektörleştirmeyi uygulamak için kullanılır; bu, öğeler üzerinde yinelemekten çok daha hızlıdır. Ayrıca, hesaplama için çok yararlı olan azaltma, biriktirme vb. gibi yaygın ve ek yöntemler sağlarlar. ufunc’lar ayrıca aşağıdaki gibi ek argümanlar alır:

where: İşlemlerin nerede gerçekleşmesi gerektiğini tanımlayan boolean dizisi veya koşul. dtype: Elemanların dönüş türünü tanımlar. out: Dönüş değerinin kopyalanması gereken çıkış dizisi.

17.2 Vektorizasyon nedir?

Yinelemeli ifadeleri vektör tabanlı işleme dönüştürmeye vektörleştirme denir. Modern CPU’lar bu tür işlemler için optimize edildiğinden daha hızlıdır.

Örneğin iki listenin elemanlarını toplayarak yeni bir liste elde edelim. Bunu yapmanın bir yolu, her iki listeyi de yinelemek ve ardından her bir öğeyi toplamaktır.

Ufunc olmadan, Python’un yerleşik zip() yöntemini kullanabiliriz:

y = [4, 5, 6, 7]
z = []

for i, j in zip(x, y):
  z.append(i + j)
print(z)

NumPy’nin ise bunun için aynı sonucu verecek olan add(x, y) adında bir ufunc’u vardır.

x = [1, 2, 3, 4]
y = [4, 5, 6, 7]
z = np.add(x, y)

print(z)

17.3 Kendi ufunc’ınızı Nasıl Oluşturursunuz?

Kendi ufunc’unuzu oluşturmak için, Python’daki normal işlevlerde yaptığınız gibi bir işlev tanımlamanız ve ardından frompyfunc() yöntemiyle bunu NumPy ufunc kitaplığınıza eklemeniz gerekir. frompyfunc() yöntemi aşağıdaki bağımsız değişkenleri alır:

function: Fonksiyonun adı. inputs: Girdi değişkenlerinin sayısı (diziler) outpusts: Çıktı dizilerinin sayısı.

Örnek olarak kendi ufunc’ımızı oluşturalım:

def myadd(x, y):
  return x+y

myadd = np.frompyfunc(myadd, 2, 1)

print(myadd([1, 2, 3, 4], [5, 6, 7, 8]))
17.3.1 Bir İşlevin ufunc Olup Olmadığını Kontrol Etmek

Bir ufunc olup olmadığını kontrol etmek için bir işlevin type değerini kontrol ederiz. Bir ufunc, <class 'numpy.ufunc'> döndürmelidir.

print(type(np.add))   # <class 'numpy.ufunc'>

Bir ufunc değilse, iki veya daha fazla diziyi birleştirmek için bu yerleşik NumPy işlevi gibi başka bir tür döndürür:

print(type(np.concatenate))   # <class 'builtin_function_or_method'

İşlev hiç tanınmazsa, bir hata döndürür:

print(type(np.blahblah))   # AttributeError: module 'numpy' has no attribute 'blahblah'

İşlevin bir if ifadesinde ufunc olup olmadığını test etmek için numpy.ufunc değerini (veya numpy için takma ad olarak np kullanıyorsanız np.ufunc) kullanın:

if type(np.add) == np.ufunc:
  print('add bir ufunc dır')
else:
  print('add bir ufunc değildir')

17.4 Basit Aritmetik İşlemler

+-* ve / aritmetik işleçleri doğrudan NumPy dizileri arasında kullanabilirsiniz, ancak bu bölümde, listeler, tuples vb. gibi herhangi bir dizi benzeri nesneyi alabilen işlevlere sahip olduğumuz yerde koşullu olarak aritmetik gerçekleştireceğiz.

Aritmetik Koşullu: Aritmetik işlemin gerçekleşmesi gereken koşulları tanımlayabileceğimiz anlamına gelir.

Tartışılan tüm aritmetik fonksiyonlar, bu koşulu belirleyebileceğimiz bir where parametresi alır.

17.4.1 Toplama (Addition)

add() işlevi, iki dizinin içeriğini toplar ve sonuçları yeni bir dizide döndürür.

arr1 = np.array([10, 11, 12, 13, 14, 15])
arr2 = np.array([20, 21, 22, 23, 24, 25])

newarr = np.add(arr1, arr2)

print(newarr)   # [30 32 34 36 38 40]
17.4.2 Çıkarma (Subtraction)

subtract() işlevi, bir dizideki değerleri başka bir dizideki değerlerle çıkarır ve sonuçları yeni bir dizide döndürür.

arr1 = np.array([10, 20, 30, 40, 50, 60])
arr2 = np.array([20, 21, 22, 23, 24, 25])

newarr = np.subtract(arr1, arr2)

print(newarr)   # [-10  -1   8  17  26  35]
17.4.3 Çarpma (Multiplication)

multiply() işlevi, bir dizideki değerleri başka bir dizideki değerlerle çarpar ve sonuçları yeni bir dizide döndürür.

arr1 = np.array([10, 20, 30, 40, 50, 60])
arr2 = np.array([20, 21, 22, 23, 24, 25])

newarr = np.multiply(arr1, arr2)

print(newarr)   # [200 420 660 920 1200 1500]
17.4.4 Bölme (Division)

divide() işlevi, bir dizideki değerleri başka bir dizideki değerlerle böler ve sonuçları yeni bir dizide döndürür.

arr1 = np.array([10, 20, 30, 40, 50, 60])
arr2 = np.array([3, 5, 10, 8, 2, 33])

newarr = np.divide(arr1, arr2)

print(newarr)   # [ 3.33333333 4. 3. 5. 25. 1.81818182]
17.4.5 Üs Alma (Power)

Power() işlevi, değerleri birinci diziden ikinci dizinin değerlerinin üssüne yükseltir ve sonuçları yeni bir dizide döndürür.

arr1 = np.array([10, 20, 30, 40, 50, 60])
arr2 = np.array([3, 5, 6, 8, 2, 33])

newarr = np.power(arr1, arr2)

print(newarr)   # [1000 3200000 729000000 -520093696 2500 0]

NOT: Ön tanımlo olarak değerler integer tanımlıdır ve sonucu integer aralığını geçen sayılarda beklenmedik sonuçlar görüyorsunuz. Bunu düzeltmek için değer aralığını float tanımlayarak genişletebilirsiniz genişletebilirsiniz.

arr1 = np.array([10, 20, 30, 40, 50, 60], dtype=float)
arr2 = np.array([3, 5, 6, 8, 2, 33], dtype=float)

newarr = np.power(arr1, arr2)

print(newarr)   # [1.00000000e+03 3.20000000e+06 7.29000000e+08 6.55360000e+12 2.50000000e+03 4.77519667e+58]
17.4.6 Kalan veya Mod (Remainder)

Hem mod() hem de remainder() işlevleri, ikinci dizideki değerlere karşılık gelen birinci dizideki değerlerin kalanını döndürür ve sonuçları yeni bir dizide döndürür.

arr1 = np.array([10, 20, 30, 40, 50, 60])
arr2 = np.array([3, 7, 9, 8, 2, 33])

newarr = np.mod(arr1, arr2)

print(newarr)   # [1  6  3  0  0 27]

remainder() işlevini kullanırken aynı sonucu elde edersiniz:

arr1 = np.array([10, 20, 30, 40, 50, 60])
arr2 = np.array([3, 7, 9, 8, 2, 33])

newarr = np.remainder(arr1, arr2)

print(newarr)   # [1  6  3  0  0 27]
17.4.7 Bölüm ve Mod (Quotient and Mod)

divmod() işlevi hem bölümü hem de modu döndürür. Dönüş değeri iki dizidir, birinci dizi bölümü içerir ve ikinci dizi modu içerir.

arr1 = np.array([10, 20, 30, 40, 50, 60])
arr2 = np.array([3, 7, 9, 8, 2, 33])

newarr = np.divmod(arr1, arr2)

print(newarr)   # (array([ 3,  2,  3,  5, 25,  1]), array([ 1,  6,  3,  0,  0, 27]))
17.4.8 Mutlak Değerler

Hem absolute() hem de abs() fonksiyonları, eleman bazında aynı mutlak işlemi yapar, ancak python’un dahili math.abs() ile karışıklığı önlemek için absolute() kullanmalıyız.

arr = np.array([-1, -2, 1, 2, 3, -4])

newarr = np.absolute(arr)

print(newarr)   # [1 2 1 2 3 4]

17.5 Ondalık Sayıları Yuvarlama

NumPy’de ondalık sayıları yuvarlamanın başlıca beş yolu vardır. Bunlar;

  • truncation
  • fix
  • rounding
  • floor
  • ceil
17.5.1 Truncation ve Fix

Ondalık sayıları kaldırmak ve sıfıra en yakın float sayı için trunc() ve fix() işlevlerini kullanabilirsiniz.

arr1 = np.trunc([-3.1666, 3.6667])
arr2 = np.fix([-3.1666, 3.6667])

print(arr1)   # [-3.  3.]
print(arr2)   #
17.5.2 Rounding

around() işlevi, eğer> = 5 ise hiçbir şey yapmazsa, önceki basamağı veya ondalık sayıyı 1 artırır. Örneğin; 3.16666 sayısı, 3.2’ye yuvarlanır. 2 sayısı ise virgülden sonraki basamak sayısını gösterir.

arr = np.around(3.1666, 2)

print(arr)   # 3.17
17.5.3 Floor

floor() işlevi ondalık en yakın küçük tam sayıya yuvarlar. Örneğin; 3.16666 sayısı, 3’e yuvarlanır.

arr = np.floor([-3.1666, 3.6667])

print(arr)   # [-4.  3.]
17.5.4 Ceil

ceil() işlevi, ondalık en yakın üst tam sayıya yuvarlar.

arr = np.ceil([-3.1666, 3.6667])

print(arr)   # [-3.  4.]

17.6 Log Almak

NumPy, 2, e ve 10 tabanında log gerçekleştirmek için işlevler sağlar. Özel bir ufunc oluşturarak herhangi bir temel için nasıl log alabileceğimizi de keşfedeceğiz. Log hesaplanamıyorsa, tüm log işlevleri öğelere -inf veya inf yerleştirir.

17.6.1 Taban 2 de Log Almak

2 tabanda log almak için log2() işlevini kullanabilirsiniz.

arr = np.arange(1, 5)

print(np.log2(arr))   # [0. 1. 1.5849625 2.]

Not: arange(1, 5) işlevi, 1’den (dahil) 5’e (dahil değil) başlayan tam sayılara sahip bir dizi döndürür.

17.6.2 Taban 10 da Log Almak

10 tabanda log almak için log10() işlevini kullanabilirsiniz.

arr = np.arange(1, 5)

print(np.log10(arr))   # [0. 0.30103 0.47712125 0.60205999]
17.6.3 Natural Log veya Taban e’de Log Almak

e tabanında almak için log() işlevini kullanabilirsiniz.

arr = np.arange(1, 10)

print(np.log(arr))   # [0. 0.69314718 1.09861229 1.38629436]
17.6.4 Herhangi Bir Tabanda Log Almak

NumPy herhangi bir tabanda log almak için herhangi bir işlev sağlamaz, bu nedenle frompyfunc() işlevini buit-in işlev math.log() ile birlikte iki giriş parametresi ve bir çıkış parametresi ile kullanabiliriz:

from math import log
import numpy as np

nplog = np.frompyfunc(log, 2, 1)

print(nplog(100, 15))   # 1.7005483074552052

17.7 NumPy Toplama (Summations)

Addition ve Summations işlemlerinin her ikisi de toplama işlemi yapar. Fakat Addition, iki argüman arasında yapılırken, Summations n öğenin üzerinde gerçekleşir.

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

newarr = np.add(arr1, arr2)   # [2 4 6]
newarr = np.sum(arr1, arr2)   # 12

print(newarr)
17.7.1 Axis İle Toplama

axis=1 belirtirseniz, NumPy her dizideki sayıları toplar.

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

newarr = np.sum([arr1, arr2], axis=1)

print(newarr)   # [6 6]
17.7.2 Kümülatif Toplama

Kümülatif toplam, elemanları diziye kısmen eklemek anlamına gelir. Örneğin. [1, 2, 3, 4]‘ün kısmi toplamı [1, 1+2, 1+2+3, 1+2+3+4] = [1, 3, 6, 10] olacaktır. cumsum() işleviyle kısmi toplama işlevi yapabiliriz.

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

newarr = np.cumsum(arr)

print(newarr)   # [1 3 6]

17.8 NumPy Çarpım (Products)

Bir dizideki öğelerin çarpımını bulmak için prod() işlevini kullanabiliriz.

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

x = np.prod(arr)

print(x)   # 24

Sonuç: 24’tür çünkü 1*2*3*4 = 24

arr1 = np.array([1, 2, 3, 4])
arr2 = np.array([5, 6, 7, 8])

x = np.prod([arr1, arr2])

print(x)   # 40320

Sonuç: 40320 çünkü 1*2*3*4*5*6*7*8 = 40320

17.8.1 Axis İle Çarpım

axis=1 belirtirseniz, NumPy her dizideki sayıları çarpar.

arr1 = np.array([1, 2, 3, 4])
arr2 = np.array([5, 6, 7, 8])

newarr = np.prod([arr1, arr2], axis=1)

print(newarr)   # [24 1680]
17.8.2 Kümülatif Toplama

Kümülatif çarpım, elemanları diziye kısmen çarpma anlamına gelir. Örneğin. [1, 2, 3, 4]‘ün kısmi çarğımı [1, 12, 123, 1234] = [1, 3, 6, 10] olacaktır. cumprod() işleviyle kısmi çarpma işlevi yapabiliriz.

arr = np.array([5, 6, 7, 8])

newarr = np.cumprod(arr)

print(newarr)   # [5 30 210 1680]

17.9 NumPy Fark (Differences)

Ayrık bir fark, iki ardışık elemanın çıkarılması anlamına gelir. Örneğin. [1, 2, 3, 4] için ayrı fark [2-1, 3-2, 4-3] = [1, 1, 1] olur. Ayrık farkı bulmak için diff() işlevini kullanabiliriz.

arr = np.array([10, 15, 25, 5])

newarr = np.diff(arr)

print(newarr)   # [5 10 -20]

Sonuç: [5 10 -20] çünkü 15-10 = 5, 25-15 = 10 ve 5-25 = -20

Bu işlemi n parametresini vererek tekrar tekrar yapabiliriz. Örneğin. [1, 2, 3, 4] için n=2 ile ayrık fark [2-1, 3-2, 4-3] = [1, 1, 1] olur, ardından n=2 olduğundan bunu yeni sonuçla bir kez daha yapacak: [1-1, 1-1] = [0, 0]

arr = np.array([10, 15, 25, 5])

newarr = np.diff(arr, n=2)

print(newarr)   # [5 -30]

Sonuç: [5-30] çünkü: 15-10 = 5, 25-15 = 10 ve 5-25 = -20 VE 10-5 = 5 ve -20-10 = -30

17.10 NumPy İle EKOK Bulmak

En Düşük Ortak Kat (EKOK), her iki sayının ortak katı olan en küçük sayıdır.

num1 = 4
num2 = 6

x = np.lcm(num1, num2)

print(x)   # 12

Sonuç: 12, çünkü bu her iki sayının en küçük ortak katıdır (4 3 = 12 ve 6 2 = 12).

17.10.1 NumPy Dizideki Elemanlardan EKOK Bulmak

Bir dizideki tüm değerlerin En Küçük Ortak Katını bulmak için, reduce() yöntemini kullanabilirsiniz. reduce() yöntemi her ögede ufunc kullanır, burada lcm(), ve diziyi bir boyut küçültür.

arr = np.array([3, 6, 9])

x = np.lcm.reduce(arr)

print(x)   # 18

Sonuç: 18, çünkü bu üç sayının en küçük ortak katıdır (3 6 = 18, 6 3 = 18 ve 9 * 2 = 18).

1’den 10’a kadar tüm tam sayıları içeren bir dizinin EKOK’unı bulalım:

arr = np.arange(1, 11)

x = np.lcm.reduce(arr)

print(x)   # 2520

17.11 NumPy İle EBOB Bulmak

En Büyük Ortak Bölen (EBOB), her iki sayının ortak bir faktörü olan en büyük sayıdır.

num1 = 6
num2 = 9

x = np.gcd(num1, num2)

print(x)   # 3

Sonuç: 3, çünkü bu, her iki sayının bölünebileceği en yüksek sayıdır (6/3 = 2 ve 9/3 = 3).

17.11.1 NumPy Dizideki Elemanlardan EBOB Bulmak

Bir dizideki tüm değerlerin En Büyük Ortak Bölenini bulmak için, reduce() yöntemini kullanabilirsiniz. reduce() yöntemi her ögede ufunc kullanır, burada gcd(), ve diziyi bir boyut küçültür.

arr = np.array([20, 8, 32, 36, 16])

x = np.gcd.reduce(arr)

print(x)   # 4

17.12 NumPy Trigonometrik Fonksiyonlar

NumPy, radyan cinsinden değerler alan ve sonuç olarak sin, cos ve tan değerlerini üreten ufunc sin()cos() ve tan()‘ı sağlar.

Örnek olarak PI/2’nin sinüs değerini bulalım:

x = np.sin(np.pi/2)

print(x)   # 1.0

Dizideki tüm değerler için sinüs değerlerini bulalım:

arr = np.array([np.pi/2, np.pi/3, np.pi/4, np.pi/5])

x = np.sin(arr)

print(x)   # [1. 0.8660254  0.70710678 0.58778525]
17.12.1 Dereceleri Radyanlara Dönüştürmek

Varsayılan olarak tüm trigonometrik fonksiyonlar parametre olarak radyan alır, ancak radyanları dereceye dönüştürebiliriz ve bunun tersini NumP’de de yapabiliriz.

Not: radyan değerleri pi/180 * derece değerleridir.

arr = np.array([90, 180, 270, 360])

x = np.deg2rad(arr)

print(x)   # [1.57079633 3.14159265 4.71238898 6.28318531]
17.12.2 Radyanları Derecelere Dönüştürmek

Aşağıdaki dizi dizisindeki tüm değerleri dereceye dönüştürelim:

arr = np.array([np.pi/2, np.pi, 1.5*np.pi, 2*np.pi])

x = np.rad2deg(arr)

print(x)   # [ 90. 180. 270. 360.]
17.12.3 Açı Bulmak

sin, cos, tan değerlerinden açı bulabiliriz. NumPy, verilen karşılık gelen sin, cos ve tan değerleri için radyan değerleri üreten ufuncs arcsin()arccos() ve arctan() sağlar.

x = np.arcsin(1.0)

print(x)   # 1.5707963267948966
17.12.4 NumPy Dizideki Elemanlardan Açı Bulmak

Dizideki tüm sinüs değerlerinin açısını bulalım.

arr = np.array([1, -1, 0.1])

x = np.arcsin(arr)

print(x)   # [ 1.57079633 -1.57079633 0.10016742]
17.12.4 Hipotenüs

NumPy’de pisagor teoremini kullanarak hipotenüs bulabiliriz. NumPy, taban ve dikey değerleri alan ve pisagor teoremine dayalı hipotenüsü üreten hypot() işlevini sağlar.

base = 3
perp = 4

x = np.hypot(base, perp)

print(x)   # 5

17.13 NumPy Hiperbolik Fonksiyonlar

NumPy, değerleri radyan cinsinden alan ve karşılık gelen sinh, cosh ve tanh değerlerini üreten ufunc’lar sinh()cosh() ve tanh() sağlar.

Örneğin PI/2’nin sinh değerini bulalım:

x = np.sinh(np.pi/2)

print(x)   # 2.3012989023072947

Dizideki tüm değerler için cosh değerlerini bulalım:

arr = np.array([np.pi/2, np.pi/3, np.pi/4, np.pi/5])

x = np.cosh(arr)

print(x)   # [2.50917848 1.60028686 1.32460909 1.20397209]
17.13.1 Açı Bulmak

sin, cos, tan değerlerinden açı bulabiliriz. NumPy, verilen karşılık gelen sin, cos ve tan değerleri için radyan değerleri üreten ufuncs arcsinh()arccosh() ve arctanh() sağlar.

x = np.arcsinh(1.0)

print(x)   # 0.881373587019543
17.13.2 NumPy Dizideki Elemanlardan Açı Bulmak

Dizideki tüm sinüs değerlerinin açısını bulalım.

arr = np.array([0.1, 0.2, 0.5])

x = np.arctanh(arr)

print(x)   # [0.10033535 0.20273255 0.54930614]

17.14 Numpy Küme (Set) Operasyonları

Matematikte bir küme, benzersiz öğelerden oluşan bir koleksiyondur. Kümeler, sık kesişme, birleşim ve fark işlemlerini içeren işlemler için kullanılır.

17.14.1 NumPy’de Küme Oluşturun

Herhangi bir diziden benzersiz öğeler bulmak için NumPy’nin unique() yöntemini kullanabiliriz. Örneğin. küme dizisi oluşturun, ancak küme dizilerinin yalnızca 1 boyutlu diziler olması gerektiğini unutmayın.

arr = np.array([1, 1, 1, 2, 3, 4, 5, 5, 6, 7])

x = np.unique(arr)

print(x)   # [1 2 3 4 5 6 7]

17.14.2 Küme Birleşimini (Union) Bulmak

İki dizinin birleşim değerlerini bulmak için union1d() yöntemini kullanabilirsiniz.

arr1 = np.array([1, 2, 3, 4])
arr2 = np.array([3, 4, 5, 6])

newarr = np.union1d(arr1, arr2)

print(newarr)   # [1 2 3 4 5 6]

17.14.3 Küme Kesişimini (Intersection) Bulmak

İki dizinin birleşim değerlerini bulmak için intersect1d() yöntemini kullanabilirsiniz.

arr1 = np.array([1, 2, 3, 4])
arr2 = np.array([3, 4, 5, 6])

newarr = np.intersect1d(arr1, arr2, assume_unique=True)

print(newarr)   # [3 4]

Not: intersect1d() yöntemi isteğe bağlı assume_unique bağımsız değişkenini alır ve True olarak ayarlanırsa hesaplamayı hızlandırabilir. Setlerle uğraşırken her zaman True olarak ayarlanmalıdır.

17.14.4 Küme Farkını (Difference) Bulmak

İlk kümede olup ikinci kümede olmayan değerleri bulmak için setdiff1d() yöntemini kullanabilirsiniz. Tam tersini de yapabilirsiniz.

set1 = np.array([1, 2, 3, 4])
set2 = np.array([3, 4, 5, 6])

newarr = np.setdiff1d(set1, set2, assume_unique=True)

print(newarr)  # [1 2]

Not: intersect1d() yöntemi isteğe bağlı assume_unique bağımsız değişkenini alır ve True olarak ayarlanırsa hesaplamayı hızlandırabilir. Setlerle uğraşırken her zaman True olarak ayarlanmalıdır.

17.14.5 Küme Simetrik Farkını (Symmetric Difference) Bulmak

Her iki kümenin de birbirine olan fark değerleri bulmak için setdiff1d() yöntemini kullanabilirsiniz. Tam tersini de yapabilirsiniz.

set1 = np.array([1, 2, 3, 4])
set2 = np.array([3, 4, 5, 6])

newarr = np.setxor1d(set1, set2, assume_unique=True)

print(newarr)   # [1 2 5 6]

Not: intersect1d() yöntemi isteğe bağlı assume_unique bağımsız değişkenini alır ve True olarak ayarlanırsa hesaplamayı hızlandırabilir. Setlerle uğraşırken her zaman True olarak ayarlanmalıdır.