Veri analizi söz konusu olduğunda, genellikle görselleştirene kadar neyi kaçırdığınızı fark etmezsiniz. Görselleştirmelerdeki büyük boşluklar veya aşağı doğru ani artışlar, verilerin tam olarak nerede eksik olduğunu size gösterecektir, ancak bu, paydaşlarınıza iletmek istediğiniz bir hikaye değildir.
Bazı görselleştirme araçları bu boşlukları kolaylıkla kapatabilse de, bunun için veri kaynağında halletmek genellikle en iyisidir ve işi sizin için yapması için görselleştirme aracınıza güvenmek, bunun dışında daha fazla analiz yapmanız gerekirse kullanışlı olmayacaktır. Peki kaynakta boş veya eksik değerleri nasıl doldururuz?
Doldurma: Kısa Bir Açıklama ve Örnek
Her birinin sonunda şirketinizin envanterinde kaç tane widget olduğunu takip eden, aşağıdaki envanter_log adlı tabloya benzeyen bir tablomuz olduğunu varsayalım:
Mağazanız hafta sonları kapalı olduğu için Cuma’dan Pazartesi’ye kadar stok değişikliği olmayacaktı, ancak bu aynı zamanda stoğu sayacak ve bu değeri tabloya girecek kimse olmadığı anlamına geliyor. Envanter numarasının Cuma’dan Pazartesi’ye değişmediğini varsaymak güvenli olacaktır, bu nedenle Cumartesi ve Pazar için doğru değerler, Cuma değeri ne olursa olsun olacaktır. Bunu başarmak için doldurma adı verilen bir araç uyguluyoruz. Doldurma tam olarak kulağa nasıl geliyor: ne zaman boş bir değer varsa, boş değeri değiştirmek için en son boş olmayan değeri üstten alırız.
Python’da bunu başaran birçok özellik (pandas.DataFrame.ffill() işlevi dahil) vardır, ancak bunlar neredeyse her zaman işlemi doğrudan veritabanı sunucusunda yapmaktan daha yavaştır.
Şimdi problemi tamamen inceledik, SQL’de nasıl yapılacağını anlayalım.
SQL’de Doldurma
Yukarıdaki örnek verilerimizle aynı tabloyu kullanarak, hem iç içe sorguları hem de pencere işlevlerini kullanarak boş değerleri değiştirebiliriz.
Yapmak istediğimiz ilk şey, boş değerleri olan satırları, üstündeki ilk boş olmayan değerle gruplamaktır. Bunu, tarih üzerinden envanter sütununu saymak için bir pencere işlevi kullanarak yapabiliriz:
select date,
day_of_week,
inventory,
count(inventory) over (order by date) as _grp
from inventory_log
Bu sorgu bize şuna benzeyen bir tablo döndürür:
Bu bize, boş değerleri, onlardan önceki ilk boş olmayan değerle birlikte gruplandırmamıza izin veren yeni bir sütun verir. Şimdi bir sonraki adım, bir gruplamayı paylaşan her satır için bu ilk değeri döndürmektir. Neyse ki, first_value pencere işlevi tam da bunu yapmamıza izin veriyor.
Bu işlevi zaten sahip olduklarımıza uygulamak bize şu sorguyu verir:
with grouped_table as (
select date,
day_of_week,
inventory,
count(inventory) over (order by date) as _grp
from inventory_log
)
select date,
day_of_week,
inventory,
_grp,
first_value() over (partition by _grp order by date) as filled_inventory
from grouped_table
Yukarıdaki sorgu bize aşağıdaki tabloyu verir:
Şimdi, önceki değerle değiştirilen boş değerlere sahip bir sütunumuz var.
O halde sorgumuzu bir araya getirelim:
with grouped_table as (
select date,
day_of_week,
inventory,
count(inventory) over (order by date) as _grp
from inventory_log
), final_table as(
select date,
day_of_week,
inventory,
_grp,
first_value() over (partition by _grp order by date) as
new_inventory
from grouped_table
)
select date,
day_of_week,
new_inventory
from final_table
Çıktı: