<jupyter_start><jupyter_text>**Neden NumPy**<jupyter_code>a = [1,2,3,4]
b = [2,3,4,5]
a
b #sadece en sona ne yazdiysak onu yazdirir.
import numpy as np
a = np.array([1,2,3,4])
b = np.array([2,3,4,5]) #listeleri numpy'da array olarak tanimliyoruz.
a*b #uzun uzun islemlere gerek kalmadan listeleri birbiri ile carpar.<jupyter_output><empty_output><jupyter_text>**NumPy Array'i Oluşturmak**<jupyter_code>import numpy as np
 np.array([1,2,3,4,5]) #array olusturma
 a = np.array([1,2,3,4,5])
type(a)
np.array([3.14,4,2,1,13]) #float ve int karisik array<jupyter_output><empty_output><jupyter_text>Veri saklarken sadece bir veri tipi tutabilmek için bütün sayıları ondalıklı bir değere çevirdi.<jupyter_code>np.array([3.14,4,2,1,13], dtype="int") #Veri tipini kendimiz belirledik.<jupyter_output><empty_output><jupyter_text>**Sıfırdan Array Oluşturma**<jupyter_code>import numpy as np
np.zeros(10, dtype = int)
np.ones((3,5) , dtype=int) #1'lerden olusan 3'e 5'lik 2 boyutlu array(matris)
np.full((4,5) , 3) #3'lerden olusan 4x5'lik matris
np.arange(0,31,3) #0'dan 31'e kadar 3'er 3'er artan dogrusal dizi.
np.linspace(0,1,10) #0 ile 1 arasinda 10 tane sayi olustur.
np.random.normal(10, 4, (3,4)) #ortalamasi=10, standart sapmasi=4 olan 3x4'luk matris
np.random.randint(0, 10, (3,3)) #0 ile 10 araliginde rastgele int degerlerden 3x3'luk matris<jupyter_output><empty_output><jupyter_text>**NumPy Array Özellikleri** * **ndim**: boyut sayısı* **shape**: boyut bilgisi* **size**: toplam eleman sayısı* **dtype**: array veri tipi<jupyter_code>import numpy as np
np.random.randint(10, size = 10)
a = np.random.randint(10, size = 10)
a.ndim #boyut sayisi-- Tek boyutlu bir array oldugundan 1 gelecek.
a.shape #boyut bilgisi-- Elimizdeki array tek boyutlu oldugundan sadece tek boyutunun bilgisini verecek.
a.size #eleman sayisi
 a.dtype #array'in veri tipi<jupyter_output><empty_output><jupyter_text>**İki boyutlu array oluşturalım**<jupyter_code>b = np.random.randint(10, size = (3,5)) #3x5'lik 0 ile 10 arasindaki degerlerden olusan matris.
b
b.ndim
b.shape
b.size
b.dtype<jupyter_output><empty_output><jupyter_text>**Reshaping (Array'i Yeniden Şekillendirme)** Elimizde var olan bir array'i yeniden şekillendirme işlemi yapacağız.Örneğin elimizde bir array olsun ve bunu yeniden boyutlandıralım. Fonskiyonlarımızın ürettiği çıktılar tek bir boyutta, tek bir array formundagerçekleşebiliyor. Bunları bazen tek boyuttan 2 boyuta ya da 2 boyuttan tek boyuta indirgeme işlemi gerekebiliyor. Bu ihtiyaçlarla Reshape fonksiyonu ile başa çıkmış oluyoruz.<jupyter_code>import numpy as np
np.arange(1, 10)
np.arange(1,10).reshape((3,3))<jupyter_output><empty_output><jupyter_text>**Not:** Tek boyutlu array: Vektör, 2 boyutlu array: Matris.<jupyter_code>a = np.arange(1,10)
a<jupyter_output><empty_output><jupyter_text>Elimizdeki tek boyutlu array'i 2 boyutlu matris'e çevirmek istiyoruz ama tek boyuttaki bilgisi de olduğu şekilde kalsın.<jupyter_code>a.ndim
a.reshape((1,9)) #Artık bir matristir fakat tek boyutlu vektörün taşıdığı bilgiyi taşır.
b = a.reshape((1,9)) #b artık matris.
b.ndim<jupyter_output><empty_output><jupyter_text>**Concantenation (Array Birleştirme)** **concatenate()** fonksiyonu ile array’leri birleştirebiliriz.<jupyter_code>import numpy as np
x = np.array([1,2,3])
y = np.array([4,5,6])
np.concatenate([x, y]) #İki adet tek boyutlu array birlestirme
z = np.array([7,8,9])
np.concatenate([x,y,z]) #Üç adet tek boyutlu array birleştirme<jupyter_output><empty_output><jupyter_text>İki boyutlu matrislerde ise:<jupyter_code>a = np.array([[1,2,3],
              [4,5,6]]) #el ile 2 boyutlu matris olusturma
np.concatenate([a,a]) #standart olarak satir bazinda birlestirme yapar.
np.concatenate([a,a], axis=1) #axis=0 satir, axis=1 sutun bazinda birlestirir.<jupyter_output><empty_output><jupyter_text>**Splitting (Array Ayırma)** **split()** fonksiyonu kullanılır.<jupyter_code>import numpy as np
x = np.array([1,2,3,99,99,3,2,1])
np.split(x, [3,5]) #3. indise kadar ayir, sonra 5. indise kadar ayir, sonra sona kadar.<jupyter_output><empty_output><jupyter_text>split fonksiyonuna girilen indis sayısı **n** ise çıktı array sayısı **n+1** olur<jupyter_code>a,b,c = np.split(x, [3,5])
a
b
c<jupyter_output><empty_output><jupyter_text>**İki boyutlu array ayırma** **vsplit()** : dikey olarak ayırmak için kullanılır. **hsplit()** : yatay olarak ayırmak için kullanılır.<jupyter_code>m = np.arange(16).reshape(4,4) #0-16 arasinda 4x4'luk matris.
m
np.vsplit(m, [2]) # yataydaki 2. indise kadar ve sonrasini ayir.
ust, alt = np.vsplit(m, [2])
ust
alt
np.hsplit(m,[2]) #dikeyde 2. indise kadar ve sonrasini ayir.<jupyter_output><empty_output><jupyter_text>**Sorting (Sıralama)** **sort()** fonskiyonunu kullanırız.<jupyter_code>import numpy as np
v = np.array([2,1,4,3,5])
np.sort(v) #Kucukten buyuge siralar. Veri setinin orjinal yapisi bozulmadi.
v.sort() #Veri setinin orjinal yapisini degistirdi.
v<jupyter_output><empty_output><jupyter_text>**Matris Sıralama**<jupyter_code>m = np.random.normal(20,5, (3,3))#ortalamasi 20, standart sapmasi 3 olan 3x3 matris.
m
np.sort(m, axis=1) #Her bir satiri kendi icinde siralar.
np.sort(m , axis=0) #Sutunlara gore siralama yapar.<jupyter_output><empty_output><jupyter_text>**Index ile Elemana Erişmek** Tek boyutlu array'lerde eleman yakalama işlemleri listeler ile aynıdır.<jupyter_code>import numpy as np
a = np.array([1,2,3,4,5,6,7,8])
a
a[0] #0 index'li eleman
a[-1] #Sondan birinci eleman
a[0] = 100 #eleman degerini degistirmek.
a<jupyter_output><empty_output><jupyter_text>**Matrislerde elemana erişme işlemleri:**<jupyter_code>m = np.random.randint(10, size = (3,5))
m
m[0,0] #0'a 0 koordinatindaki eleman (index'e gore)
m[1,1] #1'e 1 koordinatli eleman
m[1,4]
m[1,4] = 99
m
m[1,4] = 2.2 #float eklemek istiyoruz anca ondalik kismini keserek ekleyecek.
m            #Daha onceden olusturulan bir array'in tipi sonradan ekleme ile degismez.<jupyter_output><empty_output><jupyter_text>**Slicing (Array Alt Küme İşlemleri)** **Tek boyutlu array'lerde slicing işlemleri**<jupyter_code>import numpy as np
a = np.arange(20,30)
a
a[0:3]
a[:3]
a[3:]
a[1::2] #1 index'den baslayarak 2'ser 2'ser artar.
a[0::3] #0'dan baslar 3'er 3'er artar.<jupyter_output><empty_output><jupyter_text>**Matrislerde Slicing İşlemleri**<jupyter_code>m = np.random.randint(10, size=(5,5))
m
m[:,0] #Butun satirlar, 0. sutun
m[:,1] #Butun satirlar, 1. sutun
m[0,:] #0. satir, butun sutunlar
m
m[1:3,1:2] #1. ve 2. satirlar, 1. sutun
m[::,:2] #butun satirlar, ilk 2 sutun<jupyter_output><empty_output><jupyter_text>**Alt Küme Üzerinde İşlem Yapmak** Önceki bölümde array'lerin alt kümelerine eriştik fakat burada şöyle bir durum söz konusu; Örneğin bir array'in alt kümesine eriştikten sonra bunu isimlendirip kaydettiğimizi düşünelim. Bu kaydetmiş olduğumuz isimlendirme üzerinde bir değişiklik yaptığımızda array'in orjinali de değişiyordu. Fakat bazen seçilen array'in alt kümesinde o alt kümeye özel işlemler yapılmak istenebilir. İşte bu yüzden alt kümeleri bağımsızlaştırmak isimli bir işlem yapılması gerekiyor.<jupyter_code>#Bir ornek ile yukaridaki durumu daha iyi anlayalim:
import numpy as np
a = np.random.randint(10, size=(5,5)) #5x5 matris olusturduk.
a
alt_a = a[0:3,0:2] #alt kume olusturduk
alt_a
alt_a[0,0]=999 #alt kume elemanlarinda degisiklik yaptik.
alt_a[1,1]=888
alt_a
a #orjinal matrisimiz de etkilendi.<jupyter_output><empty_output><jupyter_text>Bu durum bazen çok iş görebilmekte.  Çok büyük boyutta array'ler elimizde olduğunda onların bazı parçalarını seçip spesifik olarak onların üzerinde çalışıp ana parçanın üzerinde değişiklik yapmak açısından çok işe yarar. **copy()** metodunu kullanarak bu durumdan vazgeçebiliriz.<jupyter_code>alt_b=m[0:3,0:2].copy() #bu islemden sonraki islemler ana array'den bagimsiz olacak.
alt_b[0,0]=9999
alt_b #alt kume etkilendi
m #orjinal array etkilenmedi.<jupyter_output><empty_output><jupyter_text>**Fancy Index ile Elemanlara Erişmek** **Fancy Index** kavramı ilerleyen bölümlerde bizim için en önemli kavramlardan birisi olacak. Bize hem Pandas data frame'lerinde hem de NumPy array'lerinde ileri düzey eleman seçme imkanları vermektedir.<jupyter_code>import numpy as np
v = np.arange(0,30,3)
v
[v[1], v[2], v[3]] #eski yontemle elemanlara eristik.
#Ancak elimizde 100lerce elemanli bir array oldugunda bunu yapmak zor olacak.
al_getir = [1,3,5]
v[al_getir] #Iste buna Fancy Index denir.<jupyter_output><empty_output><jupyter_text>**Matrislerde Fancy Index Kullanımı**<jupyter_code>m = np.arange(9).reshape((3,3))
m
satir = np.array([0,1])
sutun = np.array([1,2])
m[satir, sutun]
#basit index ile fancy index
m
m[0, [1,2]] #basit index ile fancy'i ayni anda kullandik.
#slice ile fancy
m[0:, [1,2]] #basit index ile fancy'i ayni anda kullandik.
#Buradaki islemlerin teknik olarak farklı oldugunu anlamamiz gerekir.<jupyter_output><empty_output><jupyter_text>**Koşullu Eleman İşlemleri**<jupyter_code>import numpy as np
v = np.array([1,2,3,4,5])
v > 5 
v < 3
v[v < 3] #Fancy
v[v > 3] #Fancy
v[v >= 3] #Fancy
v[v == 3] #Fancy
v[v != 3] #Fancy
v
v*2
v/5
v*5/10
v**2<jupyter_output><empty_output><jupyter_text>**Matematiksel İşlemler**<jupyter_code>import numpy as np
v = np.array([1,2,3,4,5])
v
v*5<jupyter_output><empty_output><jupyter_text>Biz çarpma işlemi yapsak da arka tarafta bu işlemler bir dönüştürmeye tabi tutulup NumPy içerisindeki spesifik fonksiyonlar çalıştırılıyor.<jupyter_code>#bunlara ufunc denir.
np.subtract(v, 1) # v-1 isleminin arka planinda calisan fonksiyon
np.add(v, 1) #v+1
np.multiply(v, 4) #v*4
np.divide(v, 3) #v/3
np.power(v, 3) #v**3
np.mod(v, 2) #v%2
np.absolute(np.array([-3])) #Mutlak deger<jupyter_output><empty_output><jupyter_text>**Trigonometrik Fonksiyonlar**<jupyter_code>np.sin(360)
np.cos(180)<jupyter_output><empty_output><jupyter_text>**Logaritmik İşlemler**<jupyter_code>v = np.array([1,2,3])
np.log(v)
np.log2(v)
np.log10(v)<jupyter_output><empty_output><jupyter_text>**Numpy ile İki Bilinmeyenli Denklem Çözümü** NumPy'i daha çok matematiğin alt dalı olan Lineer Cebir alanında düşünmeliyiz.<jupyter_code>import numpy as np<jupyter_output><empty_output><jupyter_text>**5 * x0 + x1 = 12**  **x0 + 3 * x1 = 10**  Bu denklemdeki bilinmeyenlerin katsayılarını array'ler cinsinden ifade ederek numpy'in altında yer alan bir fonksiyon aracılığı ile bilinmeyen değerleri çözmüş olacağız. Bu matematiksel problemi python'ın anlayacağı formata getirmemiz gerekiyor.Bunun yolu da bilinmeyen ifadelerin katsayılarını bir vektöre koymak, **(a)**bu denklemler sonucunda oluşan değerleri bir vektöre koymak, **(b)**ve son olarak, **linalg** paketi içinde geliştirilmiş **solve** isimli fonksiyonu çalıştırmak. **(x)**<jupyter_code>a = np.array([[5,1], [1,3]])
b = np.array([12,10])
a
b
x = np.linalg.solve(a,b)
x<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13011981053218166, 'fraction_numerical': 0.03659329432525309, 'mean_word_length': 6.8598540145985405, 'pattern_counts': {'":': 0, '<': 127, '<?xml version=': 0, '>': 128, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '31', 'dir': 'jupyter-structured-clean-dedup', 'id': '557144', 'license': 'MIT', 'n_tokens_mistral': 5251, 'n_tokens_neox': 4982, 'n_words': 1087, 'path': 'Manipulation/NumPy.ipynb', 'repo_name': 'SevdanurGENC/Data-Analytics-Lecture-Notes', 'size': '10767'}