Numpy Pratik Örnekler: Yararlı teknikler
Numpy Kütüphanesi, bilimsel bilgi işlem için kullanılan bir Python kütüphanesidir. Verileri çok çeşitli şekillerde depolamak ve analiz etmek için çok boyutlu bir dizi nesnesi sağlar. Bu öğreticide, Numpy'nin diğer öğreticilerde her zaman vurgulanmayan bazı özelliklerinin örneklerini göreceksiniz. Ayrıca yeni becerilerinizi çeşitli egzersizlerle uygulama şansınız olacak.
Bu eğitimde şunları nasıl yapacağınızı öğreneceksiniz:
- Dosyalarda depolanan verilerden çok boyutlu diziler oluşturun
- NumPy dizisindeki yinelenen verileri belirleyin ve kaldırın
- Veri kümeleri arasındaki farkları uzlaştırmak için yapılandırılmış NumPy dizilerini kullanın
- Hiyerarşik verilerin belirli bölümlerini analiz edin ve grafiğini çıkarın
- Kendi işlevlerinizin vektörleştirilmiş sürümlerini oluşturun
Numpy'de yeniyseniz, başlamadan önce Python'daki veri biliminin temellerini tanımak iyi bir fikirdir. Ayrıca, grafikler oluşturmak için bu öğreticide matplotlib kullanacaksınız. Gerekli olmasa da, matplotlib ile önceden tanışmak faydalı olabilir.
Çalışma ortamınızı kurmak
Bu öğreticiye başlamadan önce, bazı ilk kurulumları yapmanız gerekir. Numpy'ye ek olarak, verilerinizi çizmek için kullanacağınız matplotlib kitaplığını yüklemeniz gerekir. Ayrıca bilgisayarınızın dosya sistemine erişmek için Python’un Pathlib
kütüphanesini de kullanacaksınız, ancak Python’un standart kütüphanesinin bir parçası olduğu için pathlib
yüklemenize gerek yok.
Öğreticinizin kurulumunun mevcut Python ortamınızdaki hiçbir şeye müdahale etmediğinden emin olmak için sanal bir ortam kullanmayı düşünebilirsiniz.
Bir Python REPL yerine kodunuzu çalıştırmak için JupyterLab içinde bir Jupyter Notebook kullanmak bir başka yararlı seçenektir. Bulgularınızı denemenize ve belgelemenize ve dosyaları hızlı bir şekilde görüntülemenize ve düzenlemenize olanak tanır. Kod ve egzersiz çözümlerinin indirilebilir sürümü Jupyter Notebook formatında sunulmaktadır.
Ortak platformlarda işleri ayarlama komutları aşağıda gösterilmiştir:
İlk kod snippet'i Windows'ta kullanılmalı ve ikinci kod parçacığı Linux + macOS içindir:
Kullandığınız Windows sürümüne bağlı olarak bir Windows PowerShell (Admin)
Terminal (Yönetici) istemi başlatın. Şimdi aşağıdaki komutları yazın:
PS> python -m venv venv\
PS> venv\Scripts\activate
(venv) PS> python -m pip install numpy matplotlib jupyterlab
(venv) PS> jupyter lab
Burada, daha sonra etkinleştirdiğiniz venv\
adlı sanal bir ortam oluşturursunuz. Aktivasyon başarılı olursa, sanal ortamın adı PowerShell isteminizden önce gelir. Ardından, bu sanal ortama numpy
ve matplotlib
ve ardından isteğe bağlı jupyterlab
yüklersiniz. Sonunda Jupyterlab'a başlıyorsunuz.
Not: Sanal ortamınızı etkinleştirdiğinizde, sisteminizin komut dosyasını çalıştıramayacağını belirten bir hata alabilirsiniz. Windows'un modern sürümleri, internetten indirilen komut dosyalarını bir güvenlik özelliği olarak çalıştırmanıza izin vermez.
Bunu düzeltmek için, set-executionpolicy remotegned
komutunu yazmanız ve ardından soruya y
yanıtlamanız gerekir. Bilgisayarınız artık Microsoft'un doğruladığı komut dosyalarını çalıştıracak. Bunu yaptıktan sonra, venv\scripts\aktivite
komutu çalışmalıdır.
Bir terminali çalıştırın ve aşağıdaki komutları yazın:
$ python -m venv venv/
$ source venv/bin/activate
(venv) $ python -m pip install numpy matplotlib jupyterlab
(venv) $ jupyter lab
Burada venv/
adında bir sanal ortam yaratırsınız ve daha sonra onu etkinleştirirsiniz. Etkinleştirme başarılı olursa sanal ortamın adı komut isteminizden önce gelir. Daha sonra, bu sanal ortama numpy
ve matplotlib
'i ve ardından isteğe bağlı jupyterlab
'ı yüklersiniz. Sonunda JupyterLab'ı başlatıyorsunuz.
İstemden önce (Venv)
ile ilgili olduğunu fark edeceksiniz. Bu, bu noktadan itibaren yaptığınız her şeyin bu ortamda kalacağı ve başka yerlerde sahip olduğunuz diğer Python işlerinden ayrı kalacağı anlamına gelir.
Artık her şeyi ayarladığınıza göre öğrenme yolculuğunuzun ana kısmına başlamanın zamanı geldi.
NumPy Örnek 1: Dosyalardan Çok Boyutlu Diziler Oluşturma
Bir NumPy dizisi oluşturduğunuzda yüksek düzeyde optimize edilmiş bir veri yapısı oluşturursunuz. Bunun nedenlerinden biri, NumPy dizisinin tüm öğelerini belleğin bitişik bir alanında saklamasıdır. Bu bellek yönetimi tekniği, verilerin aynı bellek bölgesinde saklanması anlamına gelir ve bu da erişim sürelerinin hızlı olmasını sağlar. Bu elbette oldukça arzu edilen bir durumdur ancak dizinizi genişletmeniz gerektiğinde bir sorun ortaya çıkar.
Birden çok dosyayı çok boyutlu bir diziye aktarmanız gerektiğini varsayalım. Bunları ayrı diziler halinde okuyabilir ve daha sonra np.concatenate()
kullanarak bunları birleştirebilirsiniz. Ancak, bu, ek verilerle kopyayı genişletmeden önce orijinal dizinizin bir kopya oluşturur. Orijinal dizinin bitişiğinde ilgili olmayan içeriğe sahip olabileceğinden, güncellenmiş dizinin bellekte bitişik bir şekilde var olmasını sağlamak için kopyalama gereklidir.
Bir dosyadan her yeni veri eklediğinizde sürekli kopyalama dizileri işlemeyi yavaşlatabilir ve sisteminizin belleğine savurgan olabilir. Dizinize ne kadar çok veri eklediğinizde sorun daha da kötüleşir. Bu kopyalama işlemi Numpy'ye yerleştirilmiş olsa da, bu iki adımla etkilerini en aza indirebilirsiniz:
Başlangıç dizinizi ayarlarken, onu doldurmadan önce ne kadar büyük olması gerektiğini belirleyin. Gelecekteki veri eklemelerini desteklemek için boyutunu fazla tahmin etmeyi bile düşünebilirsiniz. Bu boyutları öğrendikten sonra dizinizi önceden oluşturabilirsiniz.
İkinci adım, onu kaynak verilerle doldurmaktır. Bu veriler, genişletilmesine gerek kalmadan mevcut dizinize yerleştirilecektir.
Daha sonra üç boyutlu bir NumPy dizisinin nasıl doldurulacağını keşfedeceksiniz.
Dizileri dosya verileri ile doldurma
Bu ilk örnekte, üç boyutlu bir diziyi doldurmak için üç dosyadaki verileri kullanacaksınız. Her dosyanın içeriği aşağıda gösterilmektedir ve bu dosyaları ayrıca indirilebilir materyallerde de bulacaksınız:
İlk dosyada iki satır ve aşağıdaki içeriğe sahip üç sütun vardır:
1.1, 1.2, 1.3
1.4, 1.5, 1.6
Yine aynı boyutlara sahip olan bu ikinci dosya şunu içeriyor:
2.1, 2.2, 2.3
2.4, 2.5, 2.6
Üçüncü dosya yine aynı boyutlara sahip olup şu sayıları saklar:
3.1, 3.2, 3.3
3.4, 3.5, 3.6
Devam etmeden önce bu üç dosyayı program klasörünüze ekleyin. İndirilebilir materyaller ayrıca file10.csv
ve file11.csv
adlı iki dosya içerir ve daha sonra bunlarla çalışacaksınız.
Aşağıdaki şemada, üç dosyadan oluşturacağınız ortaya çıkan numpy dizisini göstermektedir:
Gördüğünüz gibi dizinizin ön kısmını file1.csv
, orta kısmını file2.csv
ve en üst kısmını da file3.csv
oluşturuyor. geri.
Bu diziyi oluşturmak için kullanılan kod aşağıda gösterilmiştir. Bu kodu çalıştırmadan önce, diyagramda gösterilen üç dosyayı oluşturduğunuzdan veya indirilebilir materyallerde verilen sürümleri kullandığınızdan emin olun. Her iki durumda da, bunları kodunuzu çalıştırdığınız dizine yerleştirin, ardından çalıştırın:
>>> from pathlib import Path
>>> import numpy as np
>>> array = np.zeros((3, 2, 3))
>>> print(id(array))
2250027286128
>>> for file_count, csv_file in enumerate(Path.cwd().glob("file?.csv")):
... array[file_count] = np.loadtxt(csv_file.name, delimiter=",")
...
>>> print(id(array))
2250027286128
>>> print(array.shape)
(3, 2, 3)
>>> array
array([[[1.1, 1.2, 1.3],
[1.4, 1.5, 1.6]],
[[2.1, 2.2, 2.3],
[2.4, 2.5, 2.6]],
[[3.1, 3.2, 3.3],
[3.4, 3.5, 3.6]]])
Başlangıç olarak, dosyaların her birine göz atabilir ve bilgileri kullanarak beklenen dizinin son şeklini belirleyebilirsiniz. Bu örnekte, her üç dosya da iki satır ve üç sütun halinde düzenlenmiş aynı sayıda öğeye sahiptir. Ortaya çıkan dizi daha sonra (3, 2, 3)
şeklinde bir shape
özelliğine sahip olacaktır. Diyagrama bir kez daha bakın, bunu görebileceksiniz.
1. ve 2 satırları, Numpy kütüphanesinin standart takma adı yol
sınıfının pathlib
kütüphanesinden içe aktarıldığını gösterir. Bu kütüphane, Python'un nesne yönelimli bir yaklaşım kullanarak bilgisayarınızın dosya sistemine erişmesine izin verir. Path
sınıfının nesneleri, bir dosya yolu belirtmenize izin verir ve ayrıca işletim sisteminize sistem çağrıları yapabilmeniz için yöntemler içerir. Bu özellik daha sonra kodda kullanılır.
Bellek alanını azaltmak için onu verilerle doldurmaya başlamadan önce bir diziyi önceden oluşturmanın ne kadar iyi bir fikir olduğunu daha önce öğrenmiştiniz. 4. satırda daha önce belirlediğiniz gibi (3, 2, 3)
şeklinde sıfırlardan oluşan bir dizi oluşturursunuz.
Ardından, dizinizi dosyalardaki verilerle doldurursunuz. 8 ve 9. satırlarda gösterilen Python'un yerleşik numaralandırıcısı
işlevini kullanarak döngü için bir file_count
değişkeninde depolanırken
Üç .csv
dosyasının her birine sırayla erişmek için Yol
'u kullanırsınız. Path.cwd()
'ı çağırarak Python'a dosyalar için mevcut çalışma dizininize bakmasını söylemiş olursunuz. Başka bir deyişle, programı çalıştırdığınız dizin. Bu, erişmek istediğiniz dosyaların adlarını belirtmek için .glob()
yöntemini çağırdığınız geçerli dizini temsil eden bir Path
nesnesi döndürür.
Bu durumda, file1.csv, file2.csv
ve dosya dizesi olarak aktarırsınız. ? .csv
. Bu, yalnızca olmalı adlı bu karakterleri eşleştiren, ancak beşinci karakteri herhangi bir karakter olabilen dosyaları seçmek için
Ne yazık ki, .glob()
Dosyaları beklediğiniz sırayla döndürmeyebilir. Bu örnekte, her bir dosyanın adı beşinci karakteri olarak tek bir hane içerdiğinden her şey beklendiği gibi çalışır. file11.csv> adlı bir dosya olsaydı, yanlış sırada okunurdu. Bunun neden olduğu ve daha sonra nasıl çözüleceği hakkında daha fazla bilgi edineceksiniz.
Not: Windows kullanırken, sıralı()
'i açıkça çağırmalısınız:
>>> for csv_file in sorted(Path.cwd().glob("file?.csv")):
... print(csv_file.name)
...
file1.csv
file2.csv
file3.csv
Göreceğiniz gibi, bu tür sıralama, numaralandırılmış dosyalarla çalışırken her zaman yeterli değildir.
Döngü döngüleri her seferinde np.loadtxt()
işlevini çağırır ve adı
özelliği kullanılarak belirtilen bir dosya adı geçirirsiniz. Ayrıca, dosyadaki her bir numarayı ayırmasına izin vermek için bir alan sınırlayıcısı olarak bir virgül (,
) kullanmasını söylersiniz. Daha sonra her dosyanın içeriği daha önce oluşturduğunuz dizisine
atanır.
Her dosyanın içeriğinin 0
ekseni boyunca doğru konuma eklendiğinden emin olmak için array[file_count]
komutunu kullanırsınız. Döngü ilk kez yürütüldüğünde, file1.csv
içeriği array[0]
'a veya eksen-0 boyunca 0 konumuna atanacaktır. Döngüdeki bir sonraki yineleme, file3.csv
file2.csv
'yi dizi[1]
'e atayacaktır. >dizi[2]. Diyagrama bir kez daha bakın, tam olarak ne olduğunu göreceksiniz.
5. ve 11. satırlarda, id (dizi)
sonucunu yazdırdınız. id()
işlevi bir nesnenin kimlik 'i döndürür. Her nesnenin benzersiz bir kimlik değeri vardır, çünkü her nesne bilgisayar belleğinde benzersiz bir yer kaplar. Kodu bilgisayarınızda çalıştırdığınızda, sayılar da birbiriyle aynı olacaktır, ancak muhtemelen gösterilenlerden farklı olacaktır.
6. ve 12. satırlarda görüntülenen kimlik değerleri, başlangıçta yalnızca sıfırlardan oluşan array
nesnesinin, daha sonra her dosyanın içeriğini içeren dizi nesnesiyle aynı olduğunu kanıtlıyor. Bu da baştan sona tek bir nesnenin kullanıldığını ve hafızanın verimli kullanıldığını gösteriyor.
Diziler bu şekilde oluşturduğunuzda, giriş dosyalarının her birinin aynı sayıda satır ve eleman sütununa sahip olduğundan emin olmak iyi bir fikirdir. Ardından, veri dosyalarınızın o kadar düzgün olmadığı durumlarla nasıl başa çıkacağınıza bakacaksınız.
Farklı Veri Boyutlarıyla Başa Çıkmak
Başlangıç olarak, bazı küçük boyutlu verileri ekleyeceksiniz. Bunu yalnızca tek satır içeren short_file.csv
adlı dosyada bulacaksınız:
4.1, 4.2, 4.3
Aşağıda gösterildiği gibi dizinizin arkasına eklemek istiyorsunuz:
Bu ikinci diziyi oluşturmak için kullanılan kodu çalıştırmadan önce, kodunuzu çalıştırdığınız aynı dizine short_file.csv
adlı dosyayı indirdiğinizden veya eklediğinizden emin olun:
>>> array = np.zeros((4, 2, 3))
>>> for file_count, csv_file in enumerate(Path.cwd().glob("file?.csv")):
... array[file_count] = np.loadtxt(csv_file.name, delimiter=",")
...
>>> array[3, 0] = np.loadtxt("short_file.csv", delimiter=",")
>>> array
array([[[1.1, 1.2, 1.3],
[1.4, 1.5, 1.6]],
[[2.1, 2.2, 2.3],
[2.4, 2.5, 2.6]],
[[3.1, 3.2, 3.3],
[3.4, 3.5, 3.6]],
[[4.1, 4.2, 4.3],
[0. , 0. , 0. ]]])
Bu sefer dört ayrı dosyada okuyorsunuz, dolayısıyla başlangıçta oluşturduğunuz dizi (4, 2, 3)
şeklinde olacaktır. Dördüncü dosyayı yerleştirmek için eksen-0 boyunca ekstra bir boyuta ihtiyacınız olacak, bu yüzden bunu 1. satırda oluşturacaksınız.
For döngüsü daha önce olduğu gibi ilk üç dosyayı okumak için kullanılır. Kısa dosyada okumak için Python'a onu dizinizde tam olarak nereye yerleştirmek istediğinizi söylemeniz gerekir. Daha önce bunu, verileri eksen-0 boyunca konum 2'ye eklemek için dizi[2]
gibi bir konum belirterek yapıyordunuz. Bu yaklaşım işe yaradı çünkü eklediğiniz veriler mevcut diziyi zaten o konumda dolduruyordu. Ancak bu kez işler farklıdır.
Python'a kısa dosyayı eksen-2'deki dizin konumu 3'ün üstünden başlayarak eklemek istediğinizi söylemek için array[3, 0]
'ı kullanırsınız. 3
, daha önce olduğu gibi eksen-2 konumunu temsil eder, ancak verilerin 0. satırdan başlayarak eklenmesi gerektiğini belirtmek için bir de 0
sağlamanız gerekir. Verilerin nereye yerleştirildiğini görmek için program çıktısının 18. ve 19. satırlarına ve ardından diyagrama bakın.
Daha önce olduğu gibi, kodun başlangıcında oluşturulan dizi nesnesi boyunca kullanılan tek nesnedir. Kodunuz birkaç kez verileri eklese de, diziyi önceden oluşturduğunuz için verimsiz kopyalama gerekmemiştir.
Diyelim ki dördüncü dosyanın çok kısa olmak yerine çok uzun olduğunu varsayalım. Sorunlu olabilecek bu tür dosyalarla nasıl başa çıkacağınızı merak ediyor olabilirsiniz. Bu sefer, ekstra bir satır olan
4.1, 4.2, 4.3
4.4, 4.5, 4.6
4.7, 4.8, 4.9
Şimdi onu aşağıda gösterilen konumda dizinize dahil etmek istiyorsunuz. Diyagramdan da görebileceğiniz gibi, dizinin geri kalanının onu karşılamak için ekstra bir satırla genişletilmesi gerekecektir:
Bu üçüncü diziyi oluşturmak için kullanılan kod aşağıda gösterilmiştir. Çalıştırmadan önce, kodunuzu çalıştırdığınız dizinde long_file.csv
adlı dosyayı indirdiğinizden veya oluşturduğunuzdan emin olun:
>>> array = np.zeros((4, 2, 3))
>>> print(id(array))
2250027278352
>>> for file_count, csv_file in enumerate(Path.cwd().glob("file?.csv")):
... array[file_count] = np.loadtxt(csv_file.name, delimiter=",")
...
>>> array = np.insert(arr=array, obj=2, values=0, axis=1)
>>> array[3] = np.loadtxt("long_file.csv", delimiter=",")
>>> print(id(array))
2250027286224
>>> array
array([[[1.1, 1.2, 1.3],
[1.4, 1.5, 1.6],
[0. , 0. , 0. ]],
[[2.1, 2.2, 2.3],
[2.4, 2.5, 2.6],
[0. , 0. , 0. ]],
[[3.1, 3.2, 3.3],
[3.4, 3.5, 3.6],
[0. , 0. , 0. ]],
[[4.1, 4.2, 4.3],
[4.4, 4.5, 4.6],
[4.7, 4.8, 4.9]]])
Bu sefer, orijinal diziniz long_file.csv
içeriğini barındıramayacak kadar kısa olduğundan, onu eksen-1 boyunca fazladan bir satırla uzatmanız gerekir. Daha sonra long_file.csv
içeriğini ekleyebilirsiniz. Bunu 9. satırda, bir eksen boyunca değer eklemenizi sağlayan bir işlev olan np.insert()
işlevini kullanarak yapabilirsiniz.
np.insert()
'a dört parametre iletirsiniz. arr
parametresi, obj
'i 2
, axis
'i < olarak ayarlarken, içine değer eklemek istediğiniz diziyi belirtir.1 ve values
parametresini 0
olarak ayarlamak, 0
değerlerini 2
dizin konumuna eklemenize olanak tanır 1
ekseni boyunca. Başka bir deyişle, şemada gösterildiği gibi dizinin alt satırı boyunca. Son olarak long_file.csv
içeriğini dizinize eklemek için, 11. satırda gösterildiği gibi bir kez daha loadtxt()
komutunu kullanırsınız.
Diyagrama ve kodunuz tarafından oluşturulan diziye bakmak için bir dakikanızı ayırın; her şeyin beklendiği gibi çalıştığını göreceksiniz.
4. ve 14. satırların, yeni verilerin eklenmesinden önceki ve sonraki dizi nesnelerinin farklı olduğunu gösterdiğine dikkat edin. Bunun nedeni, insert()
işlevinin orijinal dizinin bir kopyasını döndürmesidir. Bu bellek israfını önlemek için, başlangıç dizinizi doldurmaya başlamadan önce doğru şekilde boyutlandırdığınızdan emin olmak gerçekten iyi bir fikirdir.
Dosya siparişinin doğru olduğundan emin olmak
path.cwd(). Glob ("Dosya? veya posixPath
nesneler. Bunların her biri, dosyasıyla eşleşen bir işletim sistemi dosya yolunu ve dosya adını temsil eder. Ancak, bu dosyaların jeneratör tarafından döndürülme sırası beklediğiniz gibi değildir.
Bunun bir örneğini görmek için indirilebilir materyallerden file10.csv
ve file11.csv
adlı iki dosyayı mevcut klasörünüze ekleyin:
10.1,10.2,10.3
10.4,10.5,10.6
Muhtemelen file10.csv> 'da ne olduğunu zaten tahmin ettiniz. Eğer öyleyse, file11.csv> 'da ne olduğunu gördüğünüzde şaşırmayacaksınız:
11.1,11.2,11.3
11.4,11.5,11.6
Şimdi aşağıdaki kodu çalıştırın:
>>> for csv_file in Path.cwd().glob("file*.csv"):
... print(csv_file.name)
...
file1.csv
file10.csv
file11.csv
file2.csv
file3.csv
Bu ek dosyaların her birinin jeneratör tarafından görüldüğünden emin olmak için, eşleşme kriterlerini dosya*.csv
olarak ayarlamanız gerekir. (*
) joker karakter, bilinmeyen birçok karakteri temsil eder. (?
) joker karakterini koruduysanız, yalnızca
Not: Linux ve macOS'ta, yukarıdaki gibi sıralanan dosyaları görmek için
Yeni dosyaların muhtemelen beklediğiniz gibi sonda değil, file1.csv
ile file2.csv
arasına yerleştirildiğini göreceksiniz. Bunun nedeni dosya adlarının alfanümerik olarak sıralanmasıdır. Bu, sıralamanın dosya adlarını soldan sağa okuduğu ve bir fark bulana kadar her şeyi eşit kabul ettiği anlamına gelir. Bunu elde ettikten sonra sıralama bu farka göre yapılır.
Örneğin, her dosya adındaki karakterler analiz edildiğinde, her bir dosyanın adının ilk dört karakteri üzerinde her şey eşit kabul edilir - bu durumda dosya
. Python o zaman beşinci karakterlerden hangisinin önce geldiğine karar vermek zorunda. Bunu, her birinin Unicode karakter kodu numaralarını göz önünde bulundurarak yapar.
1
karakterinin Unicode karakter kodu 49 iken 1
ile herhangi bir dosya adı, aynı konumda 2
veya 3
ile olanlardan daha erken sıralanır.
dosya1.csv
, dosya10.csv
ve dosya11.csv
durumunda, her dosya adının beşinci karakteri aynıdır. Bu nedenle sıralama düzeni altıncı karaktere göre belirlenecektir. Unicode karakter değerleri dikkate alındığında nokta (.), sırasıyla 48 ve 49 olan 0
ve 1
karakterlerinden önce gelen 46 değerine sahiptir. . Sonuç olarak, sıralama düzeni dosya1.csv
, ardından dosya10.csv
ve ardından dosya11.csv
olacaktır.
Bunun yardımcı olup olmadığını görmek için Python'un yerleşik sorted()
işlevine bir şans vermek isteyebilirsiniz:
>>> for csv_file in sorted(Path.cwd().glob("file*.csv")):
... print(csv_file.name)
...
file1.csv
file10.csv
file11.csv
file2.csv
file3.csv
Ancak sorted()
işlevi size daha önce olduğu gibi aynı istenmeyen sonucu verdi.
Dosyaları daha doğal bir sırayla okumak için natsort
kütüphanesini kullanabilirsiniz. İlk olarak, sıralı()
işlevi yerine kullanabilirsiniz. Aşağıda bunu gösteren kod:
>>> from natsort import natsorted
>>> for csv_file in natsorted(Path.cwd().glob("file*.csv")):
... print(csv_file.name)
...
file1.csv
file2.csv
file3.csv
file10.csv
file11.csv
Sonunda dosya adlarını sıralama sorununuzu çözmeyi başardınız. Artık önceki kodunuzu bir adım daha ileri götürebilir ve dosya içeriklerini dizinizin doğru yerlerine ekleyebilirsiniz:
>>> array = np.zeros((5, 2, 3))
>>> for file_count, csv_file in enumerate(
... natsorted(Path.cwd().glob("file*.csv"))
... ):
... array[file_count] = np.loadtxt(csv_file.name, delimiter=",")
...
>>> array
array([[[ 1.1, 1.2, 1.3],
[ 1.4, 1.5, 1.6]],
[[ 2.1, 2.2, 2.3],
[ 2.4, 2.5, 2.6]],
[[ 3.1, 3.2, 3.3],
[ 3.4, 3.5, 3.6]],
[[10.1, 10.2, 10.3],
[10.4, 10.5, 10.6]],
[[11.1, 11.2, 11.3],
[11.4, 11.5, 11.6]]])
Bu sefer çeşitli dosya yollarını natsorted()
'a aktarırsınız, bu da onları muhtemelen istediğiniz şekilde sıralar. Çıktı, hem file10.csv
hem de file11.csv
içeriğinin artık diziler içinde doğru yerlerde olduğunu gösteriyor. Burada (*
) joker karakter operatörünün nasıl kullanıldığına bir kez daha dikkat edin. Ayrıca, yeni verilere yer sağlamak için array
'in bu sürümünün boyutları (5, 2, 3)
'a yükseltildi.
Not: Numaralandırılmış dosyaların sırayla işlenmesini sağlamak için yaygın olarak kullanılan bir yöntem, sayıların başındaki sıfırlarla doldurmaktır. Dosyalar file01.csv
, file02.csv
, file03.csv
, file10.csv
olarak adlandırılmışsa, ve file11.csv
ise sorted()
dosya adlarını sıralayabilir.
Gördüğünüz gibi dosyalardaki verilerden NumPy dizileri oluşturmak tamamen mümkün. Ancak farklı boyutların dikkate alındığından emin olmanız gerekir.
Devam etmeden önce, anlayışınızı test etmek için bir alıştırmayı tamamlayacaksınız. Bu, öğrenmenizi pekiştirmenize yardımcı olmak için bu eğitimde yer alan çeşitli alıştırmalardan ilkidir.
Becerilerinizi Test Etme: Dizileri Dosya Verileriyle Doldurma
Dosya verilerinden diziler oluşturma konusundaki anlayışınızı test etmenin zamanı geldi. Aşağıda gösterilen ilk görevi çözüp çözemeyeceğinize bakın:
İndirilebilir materyallerde ex1a.csv
, ex1b.csv
ve ex1c.csv
dosyalarını bulun. Şimdi, her dosyanın eklenmesine olanak sağlayacak doğru boyutta üç boyutlu bir dizi oluşturmak için öğrendiğiniz teknikleri uygulayın. Her dosyanın içeriği, 0 ekseni boyunca ayrı bir dizinin sol üst köşesine değecek şekilde eklenmelidir. ex1b.csv
dosyasının içeriğini satır olarak, ex1c.csv
dosyasının içeriğini ise sütun olarak eklemelisiniz.
Olası bir çözüm:
>>> import numpy as np
>>> from pathlib import Path
>>> array = np.zeros((3, 4, 4), dtype="i8")
>>> array[0] = np.loadtxt("ex1a.csv", delimiter=",")
>>> narrow_array = np.loadtxt("ex1b.csv", delimiter=",")
>>> narrow_array = np.insert(arr=narrow_array, values=0, obj=3, axis=0)
>>> array[1, 0] = narrow_array
>>> short_array = np.loadtxt("ex1c.csv", delimiter=",")
>>> short_array = np.insert(arr=short_array, values=0, obj=3, axis=0)
>>> array[2, :, 0] = short_array
>>> array
array([[[ 5, 10, 15, 20],
[25, 30, 35, 40],
[45, 50, 55, 60],
[65, 70, 75, 80]],
[[ 1, 3, 5, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0]],
[[ 2, 0, 0, 0],
[ 4, 0, 0, 0],
[ 6, 0, 0, 0],
[ 0, 0, 0, 0]]])
Öncelikle dosyalara bakarsınız ve verilerinizin uygun olduğundan emin olmak için (3, 4, 4)
boyutunda bir dizinin gerekli olduğunu görürsünüz. Daha sonra bu boyutta bir sıfır dizisi oluşturursunuz ve bunun tam sayıları depolayacağını belirtirsiniz. Daha sonra, array[0]
'ı veya eksen-0'ı ex1a.csv
dosyasının içeriğiyle doldurmadan önce onu array
değişkenine atarsınız. , şekle tam olarak uyan.
ex1b.csv
dosyasının yalnızca üç değeri vardır; bu, dizi[1]
'e doğrudan eklenemeyecek kadar kısa olduğu anlamına gelir. Bunu düzeltmek için önce onu narrow_array
olarak okursunuz ve ardından dizin konumu 3'e fazladan bir 0
eklemek için np.insert()
komutunu kullanırsınız, values
ve obj
parametreleriyle tanımlandığı şekliyle. Son olarak, array[1, 0] kullanarak 0 ekseni boyunca
.array
dizininin en üst satırına 1
dizinine narrow_array
öğesini eklersiniz.
ex1c.csv
dosyasının da yalnızca üç değeri vardır. Bu, sütuna uyacak şekilde ayarlamanız gerektiği anlamına gelir, böylece sonuna ekstra bir sıfır eklersiniz. Bu kez, short_array
eklemek için dizi [2, :, 0]
kullanırsınız. 0 eksen boyunca
Okuduğunuz dizileri genişletmek yerine, değerleri nereye yerleştireceğiniz konusunda alternatif olarak daha spesifik olabilirsiniz. Örneğin, fazladan 0
'ı eklemeden önce doğrudan kısa_dizi
'yi dizi[2, 0:3, 0]
'a ekleyebilirsiniz.
Bir sonraki bölümde, yapılandırılmış diziler ve bunların farklı diziler arasındaki farkları uzlaştırmak için nasıl kullanılabileceği hakkında biraz bilgi edineceksiniz.
NumPy Örnek 2: Yapılandırılmış Diziler Kullanarak Verileri Uzlaştırma
Önceki bölümde oluşturduğunuz Numpy dizileriyle, her sütunun verilerinin anlamını bilmenin bir yolu yoktu. Belirli sütunları dizin numaraları yerine anlamlı isimlerle referans alabilmeniz güzel olmaz mıydı? Yani, örneğin, queter_grades=sonuçlar [:, 1]
kullanmak yerine, bunun yerine quead_grades=sonuçları kullanabilirsiniz ["muayene_grad"]
. İyi haber! Bunu yapılandırılmış bir dizi oluşturarak yapabilirsiniz.
Yapılandırılmış bir dizi oluşturma
Bir yapılandırılmış dizi , her biri bir alan adı ve normal veri türü içeren bir dizi tuple oluşan veri türüne sahip bir Numpy dizisidir. Bunları tanımladıktan sonra, alan adını kullanarak her bir alana erişebilir ve değiştirebilirsiniz.
Aşağıdaki kod, yapılandırılmış bir Numpy dizisinin nasıl oluşturulacağı ve referans verileceğine dair bir örnek sunmaktadır:
>>> import numpy as np
>>> race_results = np.array(
... [
... ("At The Back", 1.2, 3),
... ("Fast Eddie", 1.3, 1),
... ("Almost There", 1.1, 2),
... ],
... dtype=[
... ("horse_name", "U12"),
... ("price", "f4"),
... ("position", "i4"),
... ],
... )
>>> race_results["horse_name"]
array(['At The Back', 'Fast Eddie', 'Almost There'], dtype='<U12')
>>> np.sort(race_results, order="position")[
... ["horse_name", "price"]
... ]
array([('Fast Eddie', 1.3), ('Almost There', 1.1), ('At The Back', 1.2)],
dtype={'names': ['horse_name', 'price'],
⮑ 'formats': ['<U12', '<f4'],
⮑ 'offsets': [0, 48], 'itemsize': 56})
>>> race_results[race_results["position"] == 1]["horse_name"]
array(['Fast Eddie'], dtype='<U12')
Yapılandırılmış dizi 3'ten 14'e kadar olan satırlarda tanımlanır, ancak normal bir NumPy dizisine benzeyen şeyi tanımlayan 4'ten 8'e kadar olan satırlara bakarak başlayın. Bir at yarışına ilişkin üç satır ve üç sütun veriden oluşur. Verilerden atların isimlerini kolayca seçebilirsiniz ancak diğer iki sayının ne anlama geldiğini bulmakta biraz zorlanabilirsiniz.
Bu dizi aslında satır 9'daki veri türlerinin tanımı nedeniyle yapılandırılmış bir dizidir. Her veri türü bir alan adından ve ilişkili bir veri türünden oluşur. Üç alan horse_name
, fiyat
ve konumu
'dır. İlişkili veri türleri, dizi arabirimi protokolü kodları kullanılarak tanımlanır. u12
12 karakterlik bir dizeyi tanımlarken, 4
-Byte kayan nokta ve tamsayı biçimleri belirtin , sırasıyla.
Yapılandırılmış dizinizi ayarladıktan sonra, bu alan adlarını referans sütunlara kullanabilirsiniz. 16. satırda, bir dizi yarış atı adını görüntülemek için "hors_name"
kullandınız. Son sırayı bulmak için, "
alanını np.sort()
işlevine satır 19'da geçtiniz. Bu, koşucuları son sıralarında sıraladı. Daha sonra çıktıyı yalnızca horse_name
ve fiyatı
gösterecek şekilde filtrelediniz. Son olarak, 27. satırda, kazanan atın adını seçtiniz.
Farklı dizileri uzlaştırmak
NumPy dizilerinize alan adlarını dahil etmenin birçok yararlı amacı vardır. Ayrı NumPy dizilerindeki alan adlarını eşleştirerek kayıtları eşleştirmek istediğinizi varsayalım. Bunu yapmak için dizilerinizi bir araya getirerek yalnızca her diziden eşleşen kayıtların gösterilmesini sağlarsınız. İki ilişkisel veritabanı tablosu arasında SQL iç birleşimi gerçekleştirdiyseniz bu fikir size tanıdık gelecektir. Burada kullanılan birleştirmeyi tanımlamak için iç terimi kullanılır.
Bu bölümde, iki yeni dosya ile çalışacaksınız: cashed_checks.csv
.
issued_checks.csv
dosyası dört alan içerir: check_ID
, Alacaklı
, Amount
ve Date_Issued
kodu >. Bu dosya, işletmeniz tarafından alacaklılara verilen bir dizi çeki simüle eder:
Check_ID,Payee,Amount,Date_Issued
1341,K Starmer,150.00,2024-03-29
1342,R Sunak,175.00,2024-03-29
1343,L Truss,30.00,2024-03-29
1344,B Johnson,45.00,2024-03-22
1345,T May,65.00,2024-03-22
1346,D Cameron,430.00,2024-03-22
1347,G Brown,100.00,2024-03-15
1348,T Blair,250.00,2024-03-15
1349,J Major,500.00,2024-03-15
1350,M Thatcher,220.00,2024-03-15
cashed_checks.csv
dosyası yalnızca üç alan içerir: check_id
, miktar ve date_cashed
. Bu dosya, işletmenizin alacaklıları tarafından para kazanılan bir dizi kontrolü simüle eder:
Check_ID,Amount,Date_Cashed
1341,150.00,2024-04-12
1342,175.00,2024-04-16
1343,30.00,2024-04-12
1345,65.00,2024-04-12
1346,430.00,2024-04-08
1349,500.00,2024-04-08
1350,220.00,2024-04-15
Bozdurulan çekler için alacaklı
, tarih_verilen
ve tarih_cashed
bilgilerini görmek istediğinizi varsayalım. Dikkatli bakarsanız Alacaklı
ve Tarih_Issued
ayrıntılarının cashed_checks.csv
dosyasında yer almadığını, diğer ikisinin ise alanlar vardır. İhtiyacınız olan tüm verileri görmek için her iki dosyayı da birleştirmeniz gerekir.
Isised_checks.csv> ve
dosyalarını programınızın klasörüne ekleyin, ardından bu kodu çalıştırın:
>>> import numpy.lib.recfunctions as rfn
>>> from pathlib import Path
>>> issued_dtypes = [
... ("id", "i8"),
... ("payee", "U10"),
... ("amount", "f8"),
... ("date_issued", "U10"),
... ]
>>> cashed_dtypes = [
... ("id", "i8"),
... ("amount", "f8"),
... ("date_cashed", "U10"),
... ]
>>> issued_checks = np.loadtxt(
... Path("issued_checks.csv"),
... delimiter=",",
... dtype=issued_dtypes,
... skiprows=1,
... )
>>> cashed_checks = np.loadtxt(
... Path("cashed_checks.csv"),
... delimiter=",",
... dtype=cashed_dtypes,
... skiprows=1,
... )
>>> cashed_check_details = rfn.rec_join(
... "id",
... issued_checks,
... cashed_checks,
... jointype="inner",
... )
>>> cashed_check_details[
... ["payee", "date_issued", "date_cashed"]
... ]
array([('K Starmer', '2024-03-29', '2024-04-12'),
('R Sunak', '2024-03-29', '2024-04-16'),
('L Truss', '2024-03-29', '2024-04-12'),
('T May', '2024-03-22', '2024-04-12'),
('D Cameron', '2024-03-22', '2024-04-08'),
('J Major', '2024-03-15', '2024-04-08'),
('M Thatcher', '2024-03-15', '2024-04-15')],
dtype={'names': ['payee', 'date_issued', 'date_cashed'],
⮑'formats': ['<U10', '<U10', '<U10'],
⮑'offsets': [8, 64, 104], 'itemsize': 144})
İki NumPy dizisini birleştirmek için, yapılandırılmış dizilerle çalışmanıza olanak tanıyan birkaç yeniden düzenleme yardımcı işlevinden birini kullanırsınız. Bunlara erişmek için öncelikle numpy.lib.recfunctions
kitaplık modülünü içe aktarmanız gerekir. Dosyalara erişmek için bir kez daha pathlib
kitaplığını kullanacaksınız. 1. ve 2. satırlarda içe aktarılırlar.
4 ila 15 satırlarında, hem disreed_checks.csv
dosyası hem de np.loadtext()
parametresine dtype
parametresine beslenir.
Gerçek dosyalar kodunuza göre 17 ila 29 satırlarında okunur. skiprows
parametresini < Kod> 1 . Bu, her bir dosyanın ilk satırının göz ardı edilmesini sağlayacaktır, çünkü her biri veri değil başlık bilgileri içermektedir.
Dosyalardan okunan iki NumPy dizisi daha sonra .rec_join()
yardımcı işlevi kullanılarak 31'den 36'ya kadar olan satırlarda birleştirilir. Bu fonksiyon dört parametre kullanır. İlk parametre, iki dizinin birleştirileceği alanı tanımlar. Bu durumda dizileri, her iki dosyadaki her denetimi tanımlayan benzersiz numaraları içeren id
alanlarına göre birleştirmek istersiniz.
Daha sonra ikinci ve üçüncü parametre olarak birleştirilecek dizilerin adlarını girersiniz.
Son parametre en ilginç olanıdır. jointype='inner'
'ı belirterek bir iç birleştirme gerçekleştirirsiniz. Bu, ortaya çıkan dizinin yalnızca her iki dosyadaki eşleşen kayıtları içereceği ve ödenen tüm çeklerin tüm ayrıntılarını sağlayacağı anlamına gelir. id
'si bir dosyada görünen ancak diğerinde görünmeyen herhangi bir kayıt çıktıda görünmeyecektir.
Birleştirmenin işe yaradığını doğrulamak için 38 ila 40. satırlar tarafından üretilen çıktıya bakın. cashed_check_details
dizisi alacaklı
, date_issued
ve değerlerini içerir. date_cashed
verileri. Bu alanların ilk ikisi issued_checks.csv
dosyasından, ikincisi ise cashed_checks.csv
dosyasından geldi. Gördüğünüz gibi kayıtlar doğru bir şekilde eşleştirildi.
Yinelenen alan adlarıyla uğraşmak
Şimdi kontrol miktarını görüntülemek istediğinizi varsayalım. Bunu denemek için cazip olabilirsiniz:
>>> cashed_check_details[
... [
... "payee",
... "date_issued",
... "date_cashed",
... "amount",
... ]
... ]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'amount'
KeyError
, miktar
alanı artık birleştirilen dizide mevcut olmadığı için gerçekleşti. Bu, her iki orijinal veri dosyasının her ikisi de
Artık ne denildiğini öğrenmek için önce birleştirilmiş dizinin veri türlerini görüntülersiniz. Bunlara .dtype
özelliği aracılığıyla erişirsiniz:
>>> cashed_check_details.dtype
dtype([('id', '<i8'), ('payee', '<U10'), ('amount1', '<f8'), ('amount2', '<f8'),
⮑ ('date_issued', '<U10'), ('date_cashed', '<U10')])
Çıktıya dikkatlice bakarsanız, orijinal miktar
alanlarının yeniden adlandırıldığını fark edeceksiniz. İçeriğini görmek için bu isimleri kullanmalısınız. Bu senaryoda, her iki alan da aynı verileri içerir, bu nedenle hangisini seçtiğiniz önemli değildir:
>>> cashed_check_details[
... [
... "payee",
... "date_issued",
... "date_cashed",
... "amount1",
... ]
... ]
array([('K Starmer', '2024-03-29', '2024-04-12', 150.),
('R Sunak', '2024-03-29', '2024-04-16', 175.),
('L Truss', '2024-03-29', '2024-04-12', 30.),
('T May', '2024-03-22', '2024-04-12', 65.),
('D Cameron', '2024-03-22', '2024-04-08', 430.),
('J Major', '2024-03-15', '2024-04-08', 500.),
('M Thatcher', '2024-03-15', '2024-04-15', 220.)],
dtype={'names': ['payee', 'date_issued', 'date_cashed', 'amount1'],
⮑ 'formats': ['<U10', '<U10', '<U10', '<f8'],
⮑'offsets': [8, 64, 104, 48], 'itemsize': 144})
Bu sefer çek tutarları çıktınıza dahil edilir.
Artık hangi kontrolleri yayınladığınızı ve neyin para kazandığını bildiğinize göre, şu anda keşfedilmemiş bir çek listesi görmek isteyebilirsiniz:
>>> outstanding_checks = [
... check_id
... for check_id in issued_checks["id"]
... if check_id not in cashed_checks["id"]
... ]
>>> outstanding_checks
[np.int64(1344), np.int64(1347), np.int64(1348)]
>>> [int(check_id) for check_id in outstanding_checks]
[1344, 1347, 1348]
1. satırda, liste kavramayı kullanarak outstanding_checks
adlı bir liste oluşturursunuz. Bu, issued_checks
dizisinde bulunan ancak cashed_checks
dizisinde olmayan id
değerine sahip çeklerin bir listesini içerecektir. Bunlar hala olağanüstü.
Yine, alan adını kullanarak, karşılaştırma için kullanılacak alanları hızlı bir şekilde belirleyebilir ve kodunuzu son derece okunabilir tutabilirsiniz.
Kolaylık sağlamak için, 10. satırdaki ikinci liste anlayışını kullanarak elde ettiğiniz diziden sayıları çıkarırsınız.
Tamlık için, hesabınıza verdiğiniz hesabınıza karşı dolandırıcılık yapılan herhangi bir çekin olup olmadığını öğrenmek isteyebilirsiniz:
>>> [
... check_id
... for check_id in cashed_checks["id"]
... if check_id not in issued_checks["id"]
... ]
[]
Ortaya çıkan boş liste, çok şükür böyle bir listenin olmadığını gösteriyor. Vay be!
Yinelenen Anahtar Değerlerle Başa Çıkma
NumPy dizilerine katılmadan önce yinelenen anahtar değerlerin olmadığından emin olmak önemlidir. Bunlar bire çok ilişkiler oluşturduğundan istenmeyen sonuçlara neden olabilir. Yinelenen anahtarlarınızın geçerli olduğu durumlarda, örneğin birden çoğa birleştirme işlemi gerçekleştirmeniz gerektiğinde, pandalarda merge()
işlevini kullanmak daha iyi bir alternatiftir.
Aşağıdaki kod check_list_duplicates.csv
dosyasını kullanır. Bu dosya, daha önce kullandığınız issued_checks.csv
dosyasıyla aynı yapıya sahiptir ancak yinelenen bir kayıt vardır:
>>> from pathlib import Path
>>> import numpy.lib.recfunctions as rfn
>>> issued_dtypes = [
... ("id", "i8"),
... ("payee", "U10"),
... ("amount", "f8"),
... ("date_issued", "U10"),
... ]
>>> issued_checks = np.loadtxt(
... Path("check_list_duplicates.csv"),
... delimiter=",",
... dtype=issued_dtypes,
... skiprows=1,
... )
>>> rfn.find_duplicates(np.ma.asarray(issued_checks))
masked_array(data=[(1344, 'B Johnson', 45.0, '2024-03-22'),
(1344, 'B Johnson', 45.0, '2024-03-22')],
mask=[(False, False, False, False),
(False, False, False, False)],
fill_value=(999999, 'N/A', 1e+20, 'N/A'),
dtype=[('id', '<i8'), ('payee', '<U10'),
⮑ ('amount', '<f8'), ('date_issued', '<U10')])
Yapılandırılmış bir dizide yinelenen satırları bulmak için .find_duplicates()
yardımcı işlevini kullanabilirsiniz. Bu işlev, ona eksik veya geçersiz girişler içerebilecek bir dizi olan maskelenmiş bir dizi iletmenizi gerektirir. Diziniz bu açıdan iyi olsa da, onu fonksiyona aktarmadan önce maskeli bir diziye dönüştürmeniz gerekir. Çıktının 19. satırında yinelenen bir satır olduğunu görebilirsiniz; 1344
kaydı iki kez oluşur.
Ondan kurtulmak için
>>> issued_checks = np.unique(issued_checks, axis=0)
>>> issued_checks
array([(1341, 'K Starmer', 150., '2024-03-29'),
(1342, 'R Sunak', 175., '2024-03-29'),
(1343, 'L Truss', 30., '2024-03-29'),
(1344, 'B Johnson', 45., '2024-03-22'),
(1345, 'T May', 65., '2024-03-22'),
(1346, 'D Cameron', 430., '2024-03-22'),
(1347, 'G Brown', 100., '2024-03-15'),
(1348, 'T Blair', 250., '2024-03-15'),
(1349, 'J Major', 500., '2024-03-15'),
(1350, 'M Thatcher', 220., '2024-03-15')],
dtype=[('id', '<i8'), ('payee', '<U10'),
⮑ ('amount', '<f8'), ('date_issued', '<U10')])
Yinelenen satırları kaldırmak için issued_checks
dizinizi axis=0
ile birlikte np.unique()
'a aktararak satırları kaldırmasını söyleyin. Bu, yeni bir dizi oluşturur ve yinelenen satırlar kaldırılarak yalnızca bir örnek kalır. Çıktıya baktığınızda 1344
satırının artık yalnızca bir kez göründüğünü göreceksiniz.
Becerilerinizi test etmek: dizileri bir araya getirmek
Bir sonraki mücadelenizin zamanı geldi. Bakalım bu alıştırmayı çözebilecek misiniz:
Bir havayolu, iki ayrı dosyada yolcularına verileri tutar: yolcus.csv
pasports.csv dosya. İçeriklerini tanımak için indirilebilir materyallerde bulacağınız her iki dosyaya da bir göz atın. Şimdi, aşağıdaki görevleri çözmek için becerilerinizi kullanın:
Görev 1: Her bir yolcunun adını, soyadı ve uyruğunu içeren yapılandırılmış bir dizi üretin.
Görev 2: Listede pasaportu olmayan yolcuların olup olmadığını belirleyin.
Görev 3: Listede herhangi bir yolcuya ait olmayan pasaport olup olmadığını belirleyin.
Görev 1'e olası bir çözüm şudur:
>>> import numpy as np
>>> import numpy.lib.recfunctions as rfn
>>> passenger_dtype = [
... ("passenger_no", "i8"),
... ("first_name", "U20"),
... ("last_name", "U20"),
... ]
>>> passport_dtype = [
... ("passport_no", "i8"),
... ("passenger_no", "i8"),
... ("nationality", "U20"),
... ]
>>> passengers = np.unique(
... np.loadtxt(
... "passengers.csv",
... delimiter=",",
... dtype=passenger_dtype,
... skiprows=1,
... ),
... axis=0,
... )
>>> passports = np.unique(
... np.loadtxt(
... "passports.csv",
... delimiter=",",
... dtype=passport_dtype,
... skiprows=1,
... ),
... axis=0,
... )
>>> flight_details = rfn.rec_join(
... "passenger_no",
... passengers,
... passports,
... jointype="inner",
... )
>>> flight_details[
... ["first_name", "last_name", "nationality"]
... ]
rec.array([('Olivia', 'Smith', 'British'), ('Amelia', 'Jones', 'British'),
('Isla', 'Williams', 'American'),
('Ava', 'Taylor', 'American'), ('Ivy', 'Brown', 'Austrian'),
('Freya', 'Davies', 'Norwegian'), ('Lily', 'Evans', 'French'),
('Florence', 'Wilson', 'German'), ('Mia', 'Thomas', 'Danish'),
('Willow', 'Johnson', 'Dutch'), ('Noah', 'Roberts', 'Dutch'),
('Oliver', 'Robinson', 'French'),
('George', 'Thompson', 'Danish'),
('Muhammad', 'Walker', 'Dutch'), ('Leo', 'White', 'British'),
('Harry', 'Edwards', 'American'),
('Oscar', 'Hughes', 'Spanish'),
('Archie', 'Green', 'Norwegian'), ('Henry', 'Hall', 'British')],
dtype={'names': ['first_name', 'last_name', 'nationality'],
⮑ 'formats': ['<U20', '<U20', '<U20'],
⮑ 'offsets': [8, 88, 176], 'itemsize': 256})
4. ve 10. satırlarda gösterildiği gibi yolcu_dtipi
ve passport_dtipi
olmak üzere iki liste oluşturarak başlarsınız. Bunların her biri, her sütunun veri türlerini tanımlamak için kullanılacak tanımlama dizilerini depolar. dosya verilerini tutacak yapılandırılmış dizilerde. Her bir tanımlama grubu bir alan adından ve bir veri türünden oluşur. i8
'in bir tamsayıyı belirttiğini, U20
'nin ise yirmi karakterlik bir dizeyi tanımladığını hatırlayabilirsiniz.
16. ve 26. satırlarda, her dosyadaki verileri sırasıyla yolcular
pasaportları dizilerine okursunuz. Ayrıca, yinelenen kayıtların kaldırılmasını sağlamak için np.unique()
kullanırsınız. Bunu yapmayı unutursanız, sonuçlarınızda n/a
değerlerin göründüğünü görürsünüz. Başlıklar içerdiğinden, her dosyanın en üst satırını atladığınıza dikkat edin.
36. satırda, yolcular
ve pasaportlar
dizilerinizi birleştirme anahtarı olarak passenger_no
alanlarını kullanarak birleştirirsiniz. Bu bir iç birleştirmedir, yani çıktıya yalnızca pasaportu olan yolcular dahil edilir.
43. satırda gerekli uçuş ayrıntılarını görüntülersiniz. Çıktı, passengers.csv
dosyasındaki yolcuların adlarını ve passsports.csv
dosyasındaki uyruklarını gösterir. Bu yaklaşım, verileri çıkarmak için alan adlarına sahip olmanın kolaylığından ve netliğinden yararlanır.
Görev 2'ye olası bir çözüm:
>>> passengers_without_passports = [
... passenger
... for passenger in passengers["passenger_no"]
... if passenger not in passports["passenger_no"]
... ]
>>> passengers_without_passports
[np.int64(14)]
Bu soruyu cevaplamak için, Pasaportlar
dizi. Bu durumda, Yolcu 14
pasaport detayları sağlamamıştır.
Görev 3'ün olası bir çözüm:
>>> passports_without_passengers = [
... passenger
... for passenger in passports["passenger_no"]
... if passenger not in passengers["passenger_no"]
... ]
>>> passports_without_passengers
[np.int64(21)]
Bu soruyu tekrar cevaplamak için bir liste anlama kullanırsınız, ancak bu sefer her pasaportunuzda
dizisinizde döner ve yalnızca s/dway'leri döndürür yolcularınızda görüntüleyin
dizisi. Bu durumda, var olmayan yolcu 21
'e ait pasaport ortaya çıkar.
Bir sonraki bölümde hiyerarşik verileri nasıl analiz edeceğinizi öğreneceksiniz.
Numpy Örnek 3: Hiyerarşik verileri analiz etmek ve çizmek
Hiyerarşik veriler, farklı seviyelerden oluşan verilerdir, her seviye hemen üstünde ve aşağıdakilerle bağlantılıdır. Genellikle bir ağaç diyagramı kullanılarak çizilir ve farklı seviyeler genellikle bir ebeveyn-çocuk ilişkisine sahip olarak tanımlanır.
Örneğin, her departmanda birkaç personel içeren birkaç departmana sahip bir kuruluşunuz olabilir. Kuruluş, departman verileri ve her departmanda çalışan personelin verileri arasında hiyerarşik bir ilişki vardır.
Yapılandırılmış diziler, verilere etiketlerle başvurmanıza olanak tanıdığından hiyerarşik verileri birleştirmek için çok uygundur. NumPy'yi hiyerarşik verilerle kullanmak için onu tek bir dizide birleştirebilirsiniz.
Not: Numpy dizilerini amelge()
işlevini kullanmayı düşünmelisiniz.
Bu bölümde, bir hisse portföyünü analiz etmeye bakacaksınız. Bir hisse portföyü, çeşitli şirketlerde düzenlenen hisse tahsilatına verilen addır. Bir portföy oluşturmak, yatırımcılar için yatırım riskinin yayılmasına yardımcı olduğu için akıllı bir stratejidir. Fikir şu ki, bazı hisse senetlerinde meydana gelen kayıplar, diğerlerindeki kazançlarla dengelenecek.
Hisse portföyünüz hiyerarşik veriler içerir çünkü her biri kendi günlük fiyat hareketleri koleksiyonuna sahip birden fazla yatırımdan oluşur. Bu verileri analiz ederek portföyünüzün ne kadar iyi performans gösterdiğini görebilirsiniz.
Boş Dizi Oluşturma
Bu bölümde kullanılan veriler bazı hiyerarşik verileri simüle eder. Hisselerinize sahip olduğunuz çeşitli şirketlerin listesini içeren bir dosya tuttuğunuzu varsayalım. Bu örnekte, bu bilgiyi indirdiğiniz dosyalar arasında bulunan portfolio.csv
dosyasında bulacaksınız. Burada aşağıda gösterilmiştir:
Company,Sector
Company_A,technology
Company_B,finance
Company_C,healthcare
Company_D,technology
Company_E,finance
Company_F,healthcare
şirket
sütunu şirket adlarını içerirken, sektör
sütunu şirketin ait olduğu sektörleri içerir.
Her gün, bir hafta boyunca, ilgi duyduğunuz şirketlerin her biri için hisse fiyatlarını indirir ve bunları portföy
adlı yapılandırılmış bir Numpy dizisine eklersiniz. Her günün fiyat verilerini n
bir ile beş arasında bir sayı. Örneğin, share_prices-1.csv> Pazartesi, share_prices-2.csv> Salı için fiyatlar vb.
Örnek bir hisse fiyatları dosyası aşağıda gösterilmiştir:
Company,mon
Company_A,100.5
Company_B,200.1
Company_C,50.3
Company_D,110.5
Company_E,200.1
Company_F,55.3
Bu share_prices-1.csv
dosyasında iki sütun vardır. şirket
sütunu şirketlerin adlarını görüntülerken,
Bu verileri analiz etmek için portföy
dizinizin yedi alana ihtiyacı olacaktır. Şirket adının ve ait olduğu sektörün yanı sıra, her şirketin günlük fiyatlarını tutmak için beş alana da ihtiyacınız olacak. İlk iki alan string, geri kalanı ise float olacaktır.
Aşağıda gösterilen kod ilk portföy
dizisini oluşturur:
>>> import numpy as np
>>> from pathlib import Path
>>> days = ["mon", "tue", "wed", "thu", "fri"]
>>> days_dtype = [(day, "f8") for day in days]
>>> company_dtype = [("company", "U20"), ("sector", "U20")]
>>> portfolio_dtype = np.dtype(company_dtype + days_dtype)
>>> portfolio = np.zeros((6,), dtype=portfolio_dtype)
>>> portfolio
array([('', '', 0., 0., 0., 0., 0.), ('', '', 0., 0., 0., 0., 0.),
('', '', 0., 0., 0., 0., 0.), ('', '', 0., 0., 0., 0., 0.),
('', '', 0., 0., 0., 0., 0.), ('', '', 0., 0., 0., 0., 0.)],
dtype=[('company', '<U20'), ('sector', '<U20'), ('mon', '<f8'),
⮑ ('tue', '<f8'), ('wed', '<f8'), ('thu', '<f8'), ('fri', '<f8')])
Daha önce olduğu gibi, hem numpy
hem de pathlib
kitaplıklarını kullanacaksınız, böylece bunları 1 ve 2 satırlarında içe aktarırsınız.
portföyünüzdeki her alanın alan adlarını ve veri türlerini tanımlamak için 4, 5 ve 6'da gösterilen üç listeyi oluşturarak başlarsınız. 4 satırda oluşturduğunuz
dosyasının şirket verileri için tanımlar içerir. günleri
dizisindeki her değer için bir dizi tuple içerir ve bir kayan nokta numarasını temsil eden bir veri türü f8
. company_dtype
listesi, portfolio.csv
portföy
dizisinin veri türlerini tanımlayacak gerçek veri türü nesnesini oluşturmak için company_dtype
ve days_dtype
listelerini bir araya getirirsiniz. Daha sonra, 8. satırda gösterildiği gibi np.dtype()
işlevini kullanarak sonucu bir dtype
nesnesine aktarırsınız.
Daha sonra dtype
nesnesi np.zeros()
işlevine dtype
parametresi olarak beslenir. Ayrıca her paylaşımın verileri için ayrı bir satır sağlamak üzere dizinizi (6,)
şekliyle yapılandırırsınız. Bu, çıktıda gösterildiği gibi, ilk iki alanda boş dizeler ve geri kalanında sıfırlar içeren bir dizi üretir.
Diziyi Doldurma
Artık ihtiyacınız olan tüm verileri depolayacak kadar büyük bir dizi oluşturduğunuza göre, bir sonraki adım onu doldurmaya başlamaktır. Başlangıç olarak portfolio.csv
'de saklanan şirketlerin ayrıntılarını ekleyeceksiniz:
>>> companies = np.loadtxt(
... Path("portfolio.csv"),
... delimiter=",",
... dtype=company_dtype,
... skiprows=1,
... ).reshape((6,))
>>> portfolio[["company", "sector"]] = companies
>>> portfolio
array([('Company_A', 'technology', 0., 0., 0., 0., 0.),
('Company_B', 'finance', 0., 0., 0., 0., 0.),
('Company_C', 'healthcare', 0., 0., 0., 0., 0.),
('Company_D', 'technology', 0., 0., 0., 0., 0.),
('Company_E', 'finance', 0., 0., 0., 0., 0.),
('Company_F', 'healthcare', 0., 0., 0., 0., 0.)],
dtype=[('company', '<U20'), ('sector', '<U20'), ('mon', '<f8'),
⮑ ('tue', '<f8'), ('wed', '<f8'), ('thu', '<f8'), ('fri', '<f8')])
portfolio.csv
'den veri eklemek için portfolio.csv>' dan veri eklemek için
'i loadtxt()
işlevini bir kez daha kullanıyorsunuz. .Reshape ((6,))
satırında, diziye daha önce oluşturduğunuz portföy
dizisi ile aynı şekli vermek için kullanıldığını unutmayın. Bu, portföy
içine eklemek için gereklidir.
8. satır ekleme işleminin gerçekleştiği yerdir. İki şirket
dizi alanı, portföy
'de şirket
ve sektör
alanları olarak eklenir. çıktı.
Yapılması gereken tek şey çeşitli günlük hisse fiyatlarının eklenmesidir. Bunu yapmanın kodu aşağıda gösterilmiştir:
>>> share_prices_dtype = [("company", "U20"),("day", "f8"),]
>>> for day, csv_file in zip(
... days, sorted(Path.cwd().glob("share_prices-?.csv"))
... ):
... portfolio[day] = np.loadtxt(
... csv_file.name,
... delimiter=",",
... dtype=share_prices_dtype,
... skiprows=1,
... )["day"]
>>> portfolio
array([('Company_A', 'technology', 100.5, 101.2, 102. , 101.8, 112.5),
('Company_B', 'finance', 200.1, 199.8, 200.5, 201. , 200.8),
('Company_C', 'healthcare', 50.3, 50.5, 51. , 50.8, 51.2),
('Company_D', 'technology', 110.5, 101.2, 102. , 111.8, 97.5),
('Company_E', 'finance', 200.1, 200.8, 200.5, 211. , 200.8),
('Company_F', 'healthcare', 55.3, 50.5, 53. , 50.8, 52.2)],
dtype=[('company', '<U20'), ('sector', '<U20'), ('mon', '<f8'),
⮑ ('tue', '<f8'), ('wed', '<f8'), ('thu', '<f8'), ('fri', '<f8')])
Başlamak için, günlük share_prices-
dosyalarının her birinde iki alanı tanımlayan bir liste oluşturursunuz. Bu verileri ana portföyünüze eklemek için
dizisi, bir kez daha her biri üzerinde yineleyen bir döngü oluşturursunuz, ancak bu sefer Python'un yerleşik zip()
kullanırsınız. işlev. Dosyalar daha önce öğrendiğiniz gibi sırayla işlenecektir.
Bu durumda, daha önce tanımladığınız zip()
günleri
listesini ve işlediğiniz dosyaların her birini geçersiniz. Bu, her gün için bir dizi ve dosya çifti bulunan bir dizi tuple üretir. Tuple'deki her gün döngü Günü
değişkenine atanırken, her dosya csv_file
değişkenine atanır.
Döngünün gövdesinde her dosya np.loadtxt()
kullanılarak tekrar okunur, ancak bu sefer dosyanın tamamını saklamak yerine yalnızca day
alanı verileri depolanır. . Döngünün ilk turunda bu veriler portfolio
dizisinin mon
alanına eklenir, ikinci kez tue
alanına eklenir, ve benzeri. Bunu, okunan verileri her farklı gün için portföy[gün]
'e atayarak yaptınız.
Dizinin son sürümü, şirket adını ve ait olduğu sektörü içerir. Her kayıttaki son beş sayı Pazartesi'den Cuma'ya sentler cinsinden hisse fiyatlarıdır.
Artık hiyerarşik verilerinizi yapılandırılmış bir dizide birleştirdiğinize göre, basitlik açısından alan adlarını kullanarak analiz edebilirsiniz. Daha yakından bakmak için tek bir şirketi çıkarmak istediğinizi varsayalım:
>>> portfolio[portfolio["company"] == "Company_C"]
array([('Company_C', 'healthcare', 50.3, 50.5, 51., 50.8, 51.2)],
dtype=[('company', '<U20'), ('sector', '<U20'),
⮑ ('mon', '<f8'), ('tue', '<f8'), ('wed', '<f8'),
⮑ ('thu', '<f8'), ('fri', '<f8')])
Burada, tek bir şirketi şirket
sütununda bularak çıkarırsınız. Bunu yapmak için şirketi sütun değerleri eşleşen "company_c"
portfolio ["company"] == "company_c" kullanırsınız. >. Bu yöntem, dizine sahip satırları seçmekten çok daha sezgiseldir.
Benzer şekilde, portföyünüzdeki teknoloji
şirketlerinin Cuma günü nasıl performans gösterdiğini görmek istiyorsanız şu rakamları da seçebilirsiniz:
>>> portfolio[portfolio["sector"] == "technology"]["fri"]
array([112.5, 97.5])
Teknoloji kayıtlarını görüntülemek için portföyü ["sektör"] == "teknoloji"
kullanırsınız. Ardından, yalnızca Cuma kayıtlarını görmek için, ["fri"]
kullanarak bunları filtrelersiniz.
Teknoloji şirketlerinin her birinde 250 hisseye sahip olduğunuzu varsayalım. Hafta sonunda ne kadar paraya mal olduklarını görmek isteyebilirsiniz:
>>> portfolio[portfolio["sector"] == "technology"]["fri"] * 250 * 0.01
array([281.25, 243.75])
Bunu yapmak için, portföyünüzün teknoloji
bölümlerinin her biri için Cuma rakamlarını seçmek üzere önceden öğrendiğiniz teknikleri kullanırsınız. Daha sonra bu rakamları sahip olduğunuz hisse sayısı olan 250
ile çarparsınız. Son olarak, hisse fiyatlarının sent cinsinden ifade edildiğini aklınızda tutarak, tutarları dolara çevirmek için sonucu 0,01
ile çarparsınız. Net değeri istiyorsanız tek yapmanız gereken sum()
kullanmaktır:
>>> sum(portfolio[portfolio["sector"] == "technology"]["fri"] * 250 * 0.01)
np.float64(525.0)
Portföyünüzün teknoloji
kısmı 525,00 ABD doları değerindedir.
Gördüğünüz gibi, yapılandırılmış diziler kullanmak, verilere son derece sezgisel bir şekilde erişmenizi sağlar. İşleri daha da ileri götürmek için, bir matplotlib grafiğinin temeli olarak yapılandırılmış bir dizi kullanırken bu yaklaşımı da kullanabilirsiniz. Bundan sonra yapacağınız şey bu.
Verilerin çizilmesi
Portföyünüzün teknoloji
kısmının analizini bir grafik üzerinde görüntülemek istediğinizi varsayalım. Yine yapılandırılmış bir diziyle çalıştığınız için kod sezgisel hale gelir:
>>> import matplotlib.pyplot as plt
>>> tech_mask = portfolio["sector"] == "technology"
>>> tech_sector = portfolio[tech_mask]["company"]
>>> tech_valuation = portfolio[tech_mask]["fri"] * 250 * 0.01
>>> (
... plt.bar(x=tech_sector, height=tech_valuation, data=tech_valuation)[0]
... .set_color("g")
... )
>>> plt.xlabel("Tech Companies")
>>> plt.ylabel("Friday Price ($)")
>>> plt.title("Tech Share Valuation ($)")
>>> plt.show()
İlk önce tech_mask
yardımcı dizisini oluşturursunuz. Daha sonra çizimde kullanılacak iki dizi oluşturursunuz. 4. satırda tanımlanan tech_sector
dizisi, her tech_sector
şirketinin şirket adlarını içerir. 5. satırda tanımlanan tech_valuation
dizisi, her tech_sector
şirketinin Cuma günkü değerlemelerini içerir.
7 ila 10. satırlar çubuk grafiğini oluşturun. X ekseni, Tech_sector
çubukları oluşturmak için kullanılan şirket adlarını içerirken, Height
parametresi değerlerini içerir. tech_valuation
değerleri çizilen şeydir. 11, 12, 13 ve 14 satırları eksenler için etiket üretir ve grafiğe bir başlık verir. Son olarak, arsa görüntülenir.
Yukarıdaki kodu bir Jupyter Notebook'ta çalıştırırsanız plt.show()
kullanmanıza gerek yoktur. Bunu standart Python REPL'de çalıştırırsanız, nesne referansları 11, 12 ve 13. satırlardan sonra gösterilecektir. Bunları göz ardı edebilirsiniz ve netlik sağlamak için çıktıdan kaldırılmıştır.
Ortaya çıkan grafik aşağıda gösterilmiştir:
Gördüğünüz gibi, company_a
, sadece biraz da olsa, ikisinden daha iyisini yapıyor gibi görünüyor.
Becerilerinizi Test etmek: Hiyerarşik verileri analiz etmek ve çizmek
Devam etmeden önce, işte üçüncü zorluğunuz:
Analiz için yılın her ayı için günlük ortalama ortalama sıcaklıkları toplamanız istenmiştir. Veriler london_temperatures.csv
, new_york_temperatures.csv> ve rome_temperatures.csv
dosyalarında saklanır.
Öğrendiğiniz becerileri kullanarak, her ay için dört veri değeri içeren mantıklı alan adları ve veri türleri içeren yapılandırılmış bir
Üç şehir için her aylık sıcaklığı çizmek için yapılandırılmış dizinizi kullanın.
Dizi oluşturmanın olası bir çözüm:
>>> import numpy as np
>>> from pathlib import Path
>>> cities = ["london", "new_york", "rome"]
>>> cities_dtype = [(city, "i8") for city in cities]
>>> city_files_dtype = [("month", "U20"), ("temp", "i8")]
>>> weather_data_dtype = np.dtype([("month", "U20")] + cities_dtype)
>>> weather_data = np.zeros((12,), dtype=weather_data_dtype)
>>> weather_data
array([('', 0, 0, 0), ('', 0, 0, 0), ('', 0, 0, 0), ('', 0, 0, 0),
('', 0, 0, 0), ('', 0, 0, 0), ('', 0, 0, 0), ('', 0, 0, 0),
('', 0, 0, 0), ('', 0, 0, 0), ('', 0, 0, 0), ('', 0, 0, 0)],
dtype=[('month', '<U20'), ('london', '<i8'),
⮑ ('new_york', '<i8'), ('rome', '<i8')])
>>> for city in cities:
... temps = np.loadtxt(
... Path(f"{city}_temperatures.csv"),
... delimiter=",",
... dtype=city_files_dtype,
... )
... weather_data[["month", city]] = temps
...
>>> weather_data
array([('Jan', 5, 2, 8), ('Feb', 7, 2, 9), ('Mar', 9, 4, 12),
('Apr', 11, 11, 14), ('May', 14, 16, 21), ('Jun', 16, 22, 23),
('Jul', 19, 25, 26), ('Aug', 19, 24, 24), ('Sep', 17, 20, 22),
('Oct', 13, 14, 18), ('Nov', 10, 12, 13), ('Dec', 7, 9, 10)],
dtype=[('month', '<U20'), ('london', '<i8'),
⮑ ('new_york', '<i8'), ('rome', '<i8')])
Verileri kabul etmek için doğru boyutta bir dizi oluşturarak başlarsınız. Daha önce olduğu gibi, 9 ve 10. satırlarda weather_data
dizisini üretmeden önce her bir alanı ve veri türünü tanımlamak için listeler ve liste kapsamlarını kullanırsınız. Sonucu 11 ila 14'teki sonucu görebilirsiniz. Kod> ay alanı boş bir dize ile başlatılırken, her tamsayı alanı 0
olarak ayarlanır.
17. satırda, tek tek şehirler üzerinde dönmeye başlıyorsunuz. Londra için temps
dizisinde okudunuz ve 23 satırda verilerini ay
ve Londra
Weather_data
dizinizdeki alanlar. New York ve Roma verileri aynı şekilde okunur ve eklenir. Her şehir için ay etiketlerinin üzerine yazılır. Ancak bu, tüm veri kümelerinde aynı oldukları sürece iyidir.
27 ila 32 satırları tüm diziyi gösterir. Çizgi grafiği için bir olasılık aşağıdakiler olabilir:
>>> import matplotlib.pyplot as plt
>>> plt.plot(weather_data["month"], weather_data["london"])
>>> plt.plot(weather_data["month"], weather_data["new_york"])
>>> plt.plot(weather_data["month"], weather_data["rome"])
>>> plt.ylabel("Temperature (C)")
>>> plt.xlabel("Month")
>>> plt.title("Average Monthly Temperatures")
>>> plt.legend(["London", "New York", "Rome"])
>>> plt.show()
Grafiği oluşturmak için ayları X ekseni boyunca çizersiniz ve üç şehrin sıcaklıklarının her biri için Y ekseni boyunca ayrı bir çizgi oluşturursunuz. Daha sonra her iki grafik ekseninize de etiket eklersiniz ve bir başlık ve efsane eklersiniz.
Son çıktınız şöyle görünmelidir:
Gördüğünüz gibi, üç şehirden Roma sürekli olarak daha yüksek sıcaklıklara sahiptir.
Son bölümde, Numpy'nin ana verimlerinden birini ve bundan yararlanan işlevlerin nasıl yazılacağını öğreneceksiniz.
Numpy Örnek 4: Kendi vektörlü işlevlerinizi yazmak
NumPy'nin verimliliklerinden biri, programcının her satır veya öğe boyunca manuel olarak döngü yapan yavaş döngüler yazmasına gerek kalmadan dizilerin tamamı üzerinde hesaplamalar yapabilme yeteneğidir. Bunun yerine NumPy, hesaplamayı tüm dizi üzerinde gerçekleştirmek için temeldeki C dilini kullanır. Bu, vektörleştirme olarak bilinir.
Bu son bölümde aşağıda gösterilen full_portfolio.csv
dosyasıyla çalışacaksınız:
Company,Sector,Mon,Tue,Wed,Thu,Fri
Company_A,technology,100.5,101.2,102,101.8,112.5
Company_B,finance,200.1,199.8,200.5,201.0,200.8
Company_C,healthcare,50.3,50.5,51.0,50.8,51.2
Company_D,technology,110.5,101.2,102,111.8,97.5
Company_E,finance,200.1,200.8,200.5,211.0,200.8
Company_F,healthcare,55.3,50.5,53.0,50.8,52.2
Önceki bölümde kullanılan dosyaların birleşmesi olduğu için bu veriler size tanıdık gelecektir. Her sütunun başlığı daha önce olduğu gibi aynı anlama sahiptir.
Aşağıdaki kod, vektörleştirmeyi çalışırken gösterir:
>>> import numpy as np
>>> from pathlib import Path
>>> share_dtypes = [
... ("company", "U20"),
... ("sector", "U20"),
... ("mon", "f8"),
... ("tue", "f8"),
... ("wed", "f8"),
... ("thu", "f8"),
... ("fri", "f8"),
... ]
>>> portfolio = np.loadtxt(
... Path("full_portfolio.csv"),
... delimiter=",",
... dtype=share_dtypes,
... skiprows=1,
... )
>>> portfolio["fri"] - portfolio["mon"]
array([ 12. , 0.7, 0.9, -13. , 0.7, -3.1])
portföy
yapılandırılmış dizisini oluşturduktan sonra, paylaşımlarınızın hafta boyunca nasıl performans gösterdiğini görmeye karar verirsiniz. Bunu yapmak için iki dizi seçersiniz; biri Pazartesi hisse fiyatlarını, diğeri Cuma hisse fiyatlarını içerir. Haftalık değişimi görüntülemek için Pazartesi fiyatlarını Cuma fiyatlarından çıkarırsınız.
21. satırda, bir diziyi diğerinden çıkarmanıza rağmen, Numpy'nin her bir ayrı öğesini dizilerin bireysel olarak döndürdüğü için, bunlardan ayrı ayrı döngüye yönlendiren kod yazmaya gerek kalmadan çıkardığını bildirin. Bu vektörleşme.
Şimdi, analiz ettiğiniz hafta boyunca% 1'den fazla değere sahip hisse senetlerinde ekstra% 10 bonus elde ettiğinizi varsayalım. Bonus da dahil olmak üzere kârınızı bulmak için, iki vakayı düşünmeniz gerekir - bonusu ve almayan hisse senetleri. Bunu yapmak için aşağıdakileri deneyebilirsiniz:
>>> def profit_with_bonus(first_day, last_day):
... if last_day >= first_day * 1.01:
... return (last_day - first_day) * 1.1
... else:
... return last_day - first_day
...
>>> profit_with_bonus(portfolio["mon"], portfolio["fri"])
Traceback (most recent call last):
...
ValueError: The truth value of an array with more than one element is ambiguous.
⮑ Use a.any() or a.all()
1'den 5'e kadar satırlarda, karınızın fiyatının nasıl arttığına bağlı olarak karınızı döndürecek kar_with_bonus()
adlı bir işlev tanımladınız. Kâr% 1'den fazlaysa, bonus olarak% 10 daha eklersiniz.
İşlevinizi 7. satırda aradığınızda, bir ValueError
istisnasını yükseltir, çünkü kendisine geçtiğiniz dizileri yorumlayamaz. Yalnızca iki numarayı geçerseniz çalışır. Bu işlevin dizilerle çalışmasını sağlamak için okumaya devam edin.
np.vectorize()
ile Vektörizasyon İşlevselliği Ekleme
karınızı yapmak için dizilerle birlikte çalışmanızı yapmak için vektörleştirilmiş bir işlev 'a dönüştürmeniz gerekir. Bunu yapmanın bir yolu np.vectorize()
işlevini kullanmaktır. Bu işlev, orijinal işlevinizin bir versiyonunu döndürür, ancak dizileri skalerler yerine giriş olarak alan bir sürüm.
Aşağıda gösterilen kod, işlevinizi vektörsüz bir işlev haline getirir:
>>> def profit_with_bonus(first_day, last_day):
... if last_day >= first_day * 1.01:
... return (last_day - first_day) * 1.1
... else:
... return last_day - first_day
...
>>> vectorized_profit_with_bonus = np.vectorize(profit_with_bonus)
>>> vectorized_profit_with_bonus(portfolio["mon"], portfolio["fri"])
array([ 13.2 , 0.7 , 0.99, -13. , 0.7 , -3.1 ])
profit_with_bonus()
işlevinizi vektörleştirilmiş bir sürüme dönüştürmek için, onu 7. satırdaki np.vectorize()
işlevine aktarırsınız. Vektörleştirilmiş sürüm daha sonra <'ye atanır. kod>vectorized_profit_with_bonus adı.
8. satırda, yeni işlevi çağırır ve analiz etmesini istediğiniz dizileri aktarırsınız. Bu örnekte, çıktı ek bonus da dahil olmak üzere kârınızı gösterir. Sayıları daha önce yaptığınız basit kar hesaplamasıyla karşılaştırırsanız, birinci ve üçüncü şirketteki hisseleriniz için bir bonus aldığınızı fark edeceksiniz. 1. satırlarda orijinal işlevi değiştirmeniz gerekmediğine dikkat edin.
Dikkat etmeniz için np.vectorize()
kullanma ile ilgili son bir nokta, ihtiyaç duymanız durumunda orijinal işlevin hala kullanılabilir olmasıdır:
>>> in_profit(3, 5)
2.2
Bu sefer tek bir değer döndürülür. 5 - 3
, 2
olduğundan ve 2
, 3
'ün %1'inden fazla olduğundan, şuna %10 eklersiniz: 2.2
'yi edinin.
@np.vectorize
ile vektörleştirme işlevini ekleme
Az önce gördüğünüz gibi, np.vectorize()
işlevi ikinci bir işlev oluşturur; bu, kullanmanız gerekiyorsa orijinal sürümün hala mevcut olduğu anlamına gelir. Alternatif olarak, dekoratör olarak np.vectorize
komutunu kullanabilirsiniz:
>>> @np.vectorize
... def profit_with_bonus(first_day, last_day):
... if last_day >= first_day * 1.01:
... return (last_day - first_day) * 1.1
... else:
... return last_day - first_day
...
>>> profit_with_bonus(portfolio["mon"], portfolio["fri"])
array([ 13.2 , 0.7 , 0.99, -13. , 0.7 , -3.1 ])
1. satırdaki işlevinize @np.vectorize
uygulayarak, profit_with_bonus()
işlevi vektörleştirilmiş bir sürüme dönüştürülür. Bu yeni sürüm, daha önce gördüğünüz vectorized_profit_with_bonus()
işleviyle aynı şekilde çalışır. Bunu kullanmak için normalde yaptığınız gibi profit_with_bonus()
'u çağırın, ancak dizilerinizi ona ilettiğinizden emin olun. Bu, daha önce olduğu gibi aynı kâr dizisini döndürecektir.
np.vectorize()
işlevi tarafından oluşturulan sürümün aksine, profit_with_bonus()
'un orijinal skaler sürümü artık mevcut değil. Ancak, eğer ona iki skaler geçerseniz yine de çalışır ancak sonucu bir dizi olarak döndürür:
>>> in_profit(3, 5)
array(2.2)
Gördüğünüz gibi bu sefer çıktı bir dizi.
np.where()
ile mevcut vektörleştirme işlevini kullanmak
Mevcut NumPy işlevlerinin birçoğu zaten vektörleştirmeyi desteklemektedir. İhtiyaçlarınıza uygun bir işlevin mevcut olup olmadığını görmek için belgelere başvurmak iyi bir fikirdir. Örneğin, hisselerden elde ettiğiniz kârı bulmak için, kendi işlevinizi yazmak yerine hem bonus durumunu hem de normal kâr durumunu hesaba katmak için np.where()
işlevini kullanabilirsiniz:
>>> np.where(
... portfolio["fri"] > portfolio["mon"] * 1.01,
... (portfolio["fri"] - portfolio["mon"]) * 1.1,
... portfolio["fri"] - portfolio["mon"],
... )
array([ 13.2 , 0.7 , 0.99, -13. , 0.7 , -3.1 ])
Bu sefer koşulunuzu np.where()
'a aktarırsınız. Orijinal profit_with_bonus()
işlevinizin aksine, .where()
vektörleştirmeyi yerel olarak destekler. Bu durumda, iki dizi arasında bir karşılaştırma yaparak .where()
işlevini kullanırsınız. Ayrıca iki hesaplanmış diziyi de iletirsiniz. Birincisi %10 ilaveli kârı, ikincisi ise sade kârı temsil ediyor.
Şimdi, np.where()
her öğenin durumu değerlendirecek ve iki diziden birinden karşılık gelen öğeyi seçecektir. Durum true
ise, ilk diziden öğeyi kullanır ve
Becerilerinizi test etmek: Vektörsüz bir işlev yazmak
Son egzersiz mücadelenize dalmanın zamanı geldi. Neredeyse bitirdin.
Son mücadelenizde oluşturduğunuz weather_data
dizisinden minimum ve maksimum sıcaklıkları içeren iki dizi oluşturmanız istendi. Henüz yapmadıysanız, daha ileri gitmeden önce Hiyerarşik Verileri Analiz Etme ve Grafiklendirme alıştırmasının çözümündeki ilk kod bloğunu çalıştırarak weather_data
dizisini oluşturun.
Ardından, tamsayılar gibi üç skaler değeri kabul eden ve maksimum ve minimum değerleri döndüren find_min_max()
adında bir fonksiyon yazın. Şimdi, fonksiyonunuzu NumPy dizileriyle çalışacak şekilde geliştirmek için @np.vectorize
veya np.vectorize()
kullanın. İşlevinizin vektörleştirilmiş sürümünü orijinal adıyla arayabildiğinizden emin olun.
Bir başlangıç noktası olarak, ilk işleviniz şöyle görünebilir:
>>> def find_min_max(first, second, third):
... min_temp = min(first, second, third)
... max_temp = max(first, second, third)
... return min_temp, max_temp
>>> find_min_max(2, 1, 3)
(1, 3)
Başlangıç find_min_max()
işleviniz üç skaler değer alır ve en düşük ve en yüksek değerleri döndürür. weather_data
dizinizden verileri kullanmayı denerseniz, çalışmaz:
>>> london_temps = weather_data["london"]
>>> new_york_temps = weather_data["new_york"]
>>> rome_temps = weather_data["rome"]
>>> find_min_max(london_temps, new_york_temps, rome_temps)
>>> # ...
ValueError: The truth value of an array with more than one element is ambiguous.
Gördüğünüz gibi bir ValueError
istisnası oluşturdunuz. Dizilerle çalışmak için güncellemeniz gerekecek.
@np.vectorize
kullanan olası bir çözüm şu olabilir:
>>> @np.vectorize
... def find_min_max(first, second, third):
... min_temp = min(first, second, third)
... max_temp = max(first, second, third)
... return min_temp, max_temp
>>> london_temps = weather_data["london"]
>>> new_york_temps = weather_data["new_york"]
>>> rome_temps = weather_data["rome"]
>>> find_min_max(london_temps, new_york_temps, rome_temps)
(array([ 2, 2, 4, 11, 14, 16, 19, 19, 17, 13, 10, 7]),
⮑ array([ 8, 9, 12, 14, 21, 23, 26, 24, 22, 18, 13, 10]))
find_min_max()
işlevinizin vektörleştirilmiş sürümünü kullanmak için @np.vectorize
ile dekore edersiniz. Vektörleştirilmiş işlevi çağırmak için, hava verilerinin üç dizisini doğrudan aktarırsınız. Dekoratör, dizileri giriş olarak anlamasını ve bunları çıkış olarak üretmesini sağlar. İşlev, her ay için üç öğenin her birini analiz etmek için yerleşik min()
ve max()
işlevlerini kullanır ve sonucu iki dizide döndürür.
Alternatif bir çözüm, orijinal işlevinize geri dönmek ve bunun yerine np.vectorize()
işlevini kullanmak olabilir:
>>> def find_min_max(first, second, third):
... min_temp = min(first, second, third)
... max_temp = max(first, second, third)
... return min_temp, max_temp
>>> london_temps = weather_data["london"]
>>> new_york_temps = weather_data["new_york"]
>>> rome_temps = weather_data["rome"]
>>> find_min_max = np.vectorize(find_min_max)
>>> find_min_max(london_temps, new_york_temps, rome_temps)
(array([ 2, 2, 4, 11, 14, 16, 19, 19, 17, 13, 10, 7]),
⮑ array([ 8, 9, 12, 14, 21, 23, 26, 24, 22, 18, 13, 10]))
find_min_max()
işlevinizin vektörleştirilmiş sürümünü kullanmak için, np.vectorize()
'e geçersiniz ve çıktıyı find_min_max
, orijinal adını kullanarak vektörleştirilmiş sürümü çağırabilirsiniz. Bu vektörleştirilmiş sürümü çağırmak için, hava verilerinin üç dizisini doğrudan aktarırsınız.