---
title: 'Sorguyu Veriye Götürmek'
source: 'https://academia.sh/tr/kurslar/python-ile-analiz/sorguyu-veriye-goturmek'
course: 'Python ile Veri Analizi'
language: tr
updated: '2026-08-17T18:08:44+00:00'
license: 'CC BY-SA 4.0'
---

# Sorguyu Veriye Götürmek

Kurgu ölçüm ağının kaynağında 3.199 satır duruyor ve tek bir soru dört strateji ile cevaplanıyor; dördü de aynı sayıyı veriyor ama çözümleme ortamına taşınan kayıt sayısı 3.199'dan 5'e iniyor. Süzgeç kaynağa itildiğinde 835 satır, sütun seçimi de itildiğinde 1.670 değer, toplulaştırma da itildiğinde 10 değer taşınır ve kazanç 1.919 kata çıkar. Kazancın bedeli görünürlüktür: itilen toplam süzgeçten geçen 835 satırı, kaynaktaki 3.199 satırı ve grup başına satır sayısını getirmez, cevabın yanına kararı yazabilmek için taşınan değer 10'dan 27'ye çıkar ve oran 710 kata iner. Kazanç grup sayısına da bağlıdır: 3 gruplu kırılımda 3.199 kat, 15 gruplu kırılımda 426 kat, 835 gruplu kırılımda 11 kattır ve grup sayısı süzülen satır sayısına eşitlendiğinde sıfırlanır.

Önceki ders işi birden çok bölüme taşıdı ve dağıtmanın kendi kalemini saydı. Ama bütün o hesap tek
bir yönde kuruluydu: veri çözümleme ortamına **getiriliyordu**. Satırlar okunuyor, bölünüyor,
taşınıyor ve sonunda cevap ortaya çıkıyordu. Verinin durduğu yer de hesap yapabiliyorsa bu yön
tersine çevrilebilir.

Bu dersin ölçüsü tek bir sayıdır: **taşınan satır**. Aynı soru için kaynaktan kaç kayıt çıkıyor ve
süzgeç ile toplulaştırma kaynağa itildiğinde bu sayı kaça iniyor. Yanında duran ikinci sayı, o
kazancın karşılığında görünmez olan kalemdir — itilen bir hesap cevabı getirir, cevabı üreten
satırları getirmez.

- **AB21.** Kaynak kurgudur ve önceki derslerin kümesini tutar: 3.199 satır, altı sütun, 1.329
  abone, üç dönem. Aynı tohumla üretilir ve çıktı koşumdan koşuma aynıdır. **Modeldir.**
- **AB22.** Kaynak, verinin durduğu yerde hesap yapabilen bir arayüz olarak modellenir: süzgeç,
  sütun seçimi ve toplulaştırma orada çalıştırılabilir. **Modeldir.**
- **AB23.** Ölçülen şey kaynaktan çözümleme ortamına geçen satır ve değer sayısıdır; kaynağın
  içeride kaç satır taradığı bu ölçünün dışındadır.
- **AB24.** İki toplamın aynı sayılması için eşik 0,05 m³'tür, çünkü okumalar bir ondalıkla
  raporlanır ve bundan küçük bir fark yalnızca yuvarlamadan gelebilir.
- **AB25.** Soru sabittir: 2024-03 döneminde bölge başına toplam okuma. Bu dönemde 835 satır
  vardır ve doğru cevap 17.307,2 m³'tür.

## Kaynak ve Soru

```python
# kaynak.py — verinin durdugu yer bir arayuz olarak modellenir. MODELDIR:
# gercek bir uzak depo yerine, istenen isi yapip donen her satiri ve degeri
# sayan bir kaynak yazildi. Olcu, cozumleme ortamina tasinan satir ve degerdir.
TOHUM = 1246
BOLGE = ("kuzey", "dogu", "merkez", "guney", "bati")
DONEM = (("2024-01", 1329), ("2024-02", 1035), ("2024-03", 835))
YOGUNLUK = (0, 1, 2, 2, 2, 3, 4, 2, 2, 1)   # merkez agirlikli kurgu olcum agi
BASLIK = ("abone_no", "sayac_no", "donem", "bolge", "okuma_m3", "basamak")


def uretec(tohum: int):
    s = tohum & 0xFFFFFFFF

    def sonraki() -> float:
        nonlocal s
        s = (1103515245 * s + 12345) & 0xFFFFFFFF
        return s / 4294967296
    return sonraki


def basamak(o: float) -> str:
    return "0-10" if o <= 10 else "10-25" if o <= 25 else "25-40"


def kayitlar() -> list[tuple]:
    r, k = uretec(TOHUM), []
    for donem, adet in DONEM:
        for i in range(adet):
            o = round(5 + r() * 32.0, 1)
            k.append((10000 + i, f"S-{4000 + i}", donem,
                      BOLGE[YOGUNLUK[i % 10]], o, basamak(o)))
    return k


class Kaynak:
    """Ne istenirse onu doner ve donen her satiri ve degeri sayar. Suzgec,
    sutun secimi ve toplulastirma kaynakta yapilabilir."""

    def __init__(self, k: list):
        self.k, self.satir, self.deger = k, 0, 0

    def _ver(self, satirlar: list, alan: int) -> list:
        self.satir += len(satirlar)
        self.deger += len(satirlar) * alan
        return satirlar

    def hepsi(self) -> list:
        return self._ver(list(self.k), len(BASLIK))

    def suz(self, kosul, alanlar=None) -> list:
        s = [x for x in self.k if kosul(x)]
        if alanlar is None:
            return self._ver(s, len(BASLIK))
        ix = [BASLIK.index(a) for a in alanlar]
        return self._ver([tuple(x[i] for i in ix) for x in s], len(alanlar))

    def say(self, kosul) -> int:
        return self._ver([sum(1 for x in self.k if kosul(x))], 1)[0]

    def topla_genis(self, kosul, grup: str, olcu: str) -> list:
        """Toplamin yanina sayi, en kucuk ve en buyugu de koyar: bes deger."""
        gi, oi = BASLIK.index(grup), BASLIK.index(olcu)
        t = {}
        for x in self.k:
            if kosul(x):
                a = t.setdefault(x[gi], [0.0, 0, x[oi], x[oi]])
                a[0], a[1] = a[0] + x[oi], a[1] + 1
                a[2], a[3] = min(a[2], x[oi]), max(a[3], x[oi])
        return self._ver([(g, *v) for g, v in sorted(t.items())], 5)

    def topla(self, kosul, grup: str, olcu: str) -> list:
        gi, oi = BASLIK.index(grup), BASLIK.index(olcu)
        t = {}
        for x in self.k:
            if kosul(x):
                t[x[gi]] = t.get(x[gi], 0.0) + x[oi]
        return self._ver(sorted(t.items()), 2)


k0 = kayitlar()
HEDEF = "2024-03"
print(f"tohum {TOHUM}; kaynakta {len(k0)} satir, {len(BASLIK)} sutun, "
      f"{len(k0) * len(BASLIK)} deger")
print(f"soru: {HEDEF} doneminde bolge basina toplam okuma; kaynakta bu donemin "
      f"{sum(a for d, a in DONEM if d == HEDEF)} satiri var")
```

```
tohum 1246; kaynakta 3199 satir, 6 sutun, 19194 deger
soru: 2024-03 doneminde bolge basina toplam okuma; kaynakta bu donemin 835 satiri var
```

Kaynak üç iş yapabiliyor: satır süzmek, sütun seçmek ve grup başına toplam almak. Bunların hepsi
çözümleme ortamında da yapılabilir; fark yalnızca **nerede** yapıldığındadır. Arayüz her dönen
satırı ve her dönen değeri sayıyor, çünkü ölçülecek şey hesabın kendisi değil, hesabın sonucunun
kaç kayıtla ifade edildiğidir. Kaynağın içeride kaç satır taradığı bu sayının dışındadır ve AB23
bunu ayrı tutar.

## Dört İtme Derecesi

```python
# itme.py — ayni soru dort strateji ile cevaplanir. Fark, isin nerede
# yapildigidir: hepsi istemcide, suzgec kaynakta, sutun daraltma kaynakta,
# toplulastirma da kaynakta.
ESIK = 0.05   # okumalar bir ondalikla raporlanir, altindaki fark yuvarlamadandir


def istemcide_topla(satirlar, gi: int, oi: int) -> dict:
    t = {}
    for x in satirlar:
        t[x[gi]] = t.get(x[gi], 0.0) + x[oi]
    return t


def s1(kn: Kaynak) -> dict:                       # hicbir sey itilmez
    return istemcide_topla([x for x in kn.hepsi() if x[2] == HEDEF], 3, 4)


def s2(kn: Kaynak) -> dict:                       # suzgec itilir
    return istemcide_topla(kn.suz(lambda x: x[2] == HEDEF), 3, 4)


def s3(kn: Kaynak) -> dict:                       # suzgec ve sutun secimi itilir
    return istemcide_topla(
        kn.suz(lambda x: x[2] == HEDEF, ["bolge", "okuma_m3"]), 0, 1)


def s4(kn: Kaynak) -> dict:                       # toplulastirma da itilir
    return dict(kn.topla(lambda x: x[2] == HEDEF, "bolge", "okuma_m3"))


G = (34, 14, 14, 10, 12, 12)
y = lambda h: "".join(str(v).rjust(G[j]) if j else str(v).ljust(G[0])
                      for j, v in enumerate(h))
print(y(["strateji", "tasinan satir", "tasinan deger", "oran", "merkez m3", "toplam m3"]))
taban = 0
for ad, f in [("hicbir sey itilmez", s1), ("suzgec itilir", s2),
              ("suzgec ve sutun secimi itilir", s3),
              ("toplulastirma da itilir", s4)]:
    kn = Kaynak(k0)
    t = f(kn)
    taban = taban or kn.deger
    print(y([ad, kn.satir, kn.deger, f"{taban / kn.deger:.0f}x",
             round(t["merkez"], 1), round(sum(t.values()), 1)]))
kn1, kn4 = Kaynak(k0), Kaynak(k0)
t1, t4 = s1(kn1), s4(kn4)
fark = max(abs(t1[g] - t4[g]) for g in t1)
print(f"itilmemis ve itilmis hesabin bolge toplamlari arasindaki en buyuk fark "
      f"{fark:.1e} m3; esik {ESIK} m3 oldugu icin ayni sayi sayilir. Kayan noktali "
      f"toplama sirasi degisebildigi icin esitlik == ile degil esikle sinanir")
```

```
strateji                           tasinan satir tasinan deger      oran   merkez m3   toplam m3
hicbir sey itilmez                          3199         19194        1x      8752.6     17307.2
suzgec itilir                                835          5010        4x      8752.6     17307.2
suzgec ve sutun secimi itilir                835          1670       11x      8752.6     17307.2
toplulastirma da itilir                        5            10     1919x      8752.6     17307.2
itilmemis ve itilmis hesabin bolge toplamlari arasindaki en buyuk fark 0.0e+00 m3; esik 0.05 m3 oldugu icin ayni sayi sayilir. Kayan noktali toplama sirasi degisebildigi icin esitlik == ile degil esikle sinanir
```

Dört strateji de aynı cevabı veriyor: merkez bölgesinde 8.752,6 m³, toplamda 17.307,2 m³. Taşınan
satır 3.199'dan 5'e, taşınan değer 19.194'ten 10'a iniyor — **1.919 kat**. Kazanç üç ayrı itme
kararının toplamıdır ve her satır bir kararı ekliyor.

Süzgecin itilmesi taşınan satırı 3.199'dan 835'e indiriyor; oran doğrudan seçicilikten geliyor.
Sütun seçiminin itilmesi satır sayısını değiştirmiyor ama değer sayısını 5.010'dan 1.670'e
düşürüyor, çünkü altı alan yerine iki alan geliyor. Toplulaştırmanın itilmesi ise satır kavramını
değiştiriyor: artık taşınan şey kayıt değil, sonuçtur — beş grup, beş satır.

Son satır iki toplamı karşılaştırıyor. İtilmemiş ve itilmiş hesabın bölge toplamları arasındaki en
büyük fark sıfırdır, ama karşılaştırma yine de eşikle yapılır. Sebep koşumun sonucu değil, kayan
noktalı toplamanın birleşme özelliği taşımamasıdır: aynı sayılar başka bir sırada toplandığında son
basamak oynayabilir. Kaynağın grup içini hangi sırada topladığı arayüzün dışındadır ve yazılı
değildir; bu yüzden eşitlik doğrudan sınanmaz, eşik yazılır.

## Kazancın Karşılığı

```python
# denetim.py — itilen hesap sonucu getirir, sonucu ureten karari getirmez.
# Once cevabin yanina karar yazilabilmesi icin kac deger daha gerektigi,
# sonra itmenin kazancinin grup sayisiyla nasil eridigi sayilir.
TABAN = len(k0) * len(BASLIK)
kn = Kaynak(k0)
genis = kn.topla_genis(lambda x: x[2] == HEDEF, "bolge", "okuma_m3")
suzulen, tumu = kn.say(lambda x: x[2] == HEDEF), kn.say(lambda x: True)
G2 = (36, 15, 15, 10)
y2 = lambda h: "".join(str(v).rjust(G2[j]) if j else str(v).ljust(G2[0])
                       for j, v in enumerate(h))
print(y2(["cevabin yanina yazilan", "tasinan satir", "tasinan deger", "oran"]))
print(y2(["yalniz toplam", 5, 10, f"{TABAN // 10}x"]))
print(y2(["toplam, sayi, en kucuk, en buyuk", len(genis), 5 * len(genis),
          f"{TABAN // (5 * len(genis))}x"]))
print(y2(["ustune suzulen ve toplam satir", kn.satir, kn.deger,
          f"{TABAN // kn.deger}x"]))
for g, toplam, sayi, enk, enb in genis:
    if g in ("merkez", "bati"):
        print(f"{g:8s} toplam {toplam:8.1f} m3, {sayi:4d} satir, ortalama "
              f"{toplam / sayi:5.2f} m3, aralik {enk}-{enb} m3")
print(f"suzgecten gecen satir {suzulen}, kaynaktaki toplam satir {tumu}; itilen "
      f"toplam bu iki sayiyi getirmez ve grup basina satir sayisini da getirmez")

# Itmenin kazanci grup sayisina baglidir: sonuc satiri grup sayisi kadardir.
print(y2(["gruplama anahtari", "grup sayisi", "tasinan deger", "oran"]))
for ad, alan in [("basamak", "basamak"), ("bolge", "bolge"),
                 ("bolge + basamak", None), ("abone_no", "abone_no")]:
    kn2 = Kaynak(k0)
    if alan is None:
        t = {}
        for x in k0:
            if x[2] == HEDEF:
                t[(x[3], x[5])] = t.get((x[3], x[5]), 0.0) + x[4]
        kn2._ver(sorted(t.items()), 3)
    else:
        kn2.topla(lambda x: x[2] == HEDEF, alan, "okuma_m3")
    print(y2([ad, kn2.satir, kn2.deger, f"{TABAN // kn2.deger}x"]))
ham = Kaynak(k0)
ham.suz(lambda x: x[2] == HEDEF, ["bolge", "okuma_m3"])
print(f"suzulmus ve daraltilmis ham dilim {ham.deger} deger tasir; abone anahtarli "
      f"itilen toplulastirma {2 * suzulen} deger tasir")
print(f"grup sayisi suzulen satir sayisina esitlendiginde itmenin kazanci sifirlanir: "
      f"{suzulen} grup, {suzulen} satir")
```

```
cevabin yanina yazilan                tasinan satir  tasinan deger      oran
yalniz toplam                                     5             10     1919x
toplam, sayi, en kucuk, en buyuk                  5             25      767x
ustune suzulen ve toplam satir                    7             27      710x
bati     toplam   1789.1 m3,   83 satir, ortalama 21.56 m3, aralik 5.0-37.0 m3
merkez   toplam   8752.6 m3,  418 satir, ortalama 20.94 m3, aralik 5.0-37.0 m3
suzgecten gecen satir 835, kaynaktaki toplam satir 3199; itilen toplam bu iki sayiyi getirmez ve grup basina satir sayisini da getirmez
gruplama anahtari                       grup sayisi  tasinan deger      oran
basamak                                           3              6     3199x
bolge                                             5             10     1919x
bolge + basamak                                  15             45      426x
abone_no                                        835           1670       11x
suzulmus ve daraltilmis ham dilim 1670 deger tasir; abone anahtarli itilen toplulastirma 1670 deger tasir
grup sayisi suzulen satir sayisina esitlendiginde itmenin kazanci sifirlanir: 835 grup, 835 satir
```

İlk tablo dersin gizlenen kararıdır. İtilen toplulaştırma on değer getirir ve o on değerin yanında
hiçbir karar yazılı değildir. Merkez bölgesinin 8.752,6 m³'ünün 418 satırdan mı yoksa 4 satırdan mı
geldiği sonucun içinde yoktur; süzgeçten 835 satır geçtiği de, kaynakta 3.199 satır olduğu da
yoktur. Bu kalemleri de istemek taşınan değeri 10'dan 27'ye çıkarır ve kazancı 1.919 kattan 710
kata indirir. **Kursun kuralı burada ödenir:** kararı yazılmayan sayı ölçülmemiş sayılır, ve o
kararı yazmanın bu kaynakta bedeli 17 değerdir.

Sayıların kendisi de karar taşıyor. Merkez bölgesi 418 satırda ortalama 20,94 m³, batı bölgesi 83
satırda ortalama 21,56 m³ veriyor. Toplamlar 8.752,6 ile 1.789,1 m³ ve aralarında beş kat fark var;
ortalamalar birbirine yakın. Yalnız toplamı gören bir rapor merkez bölgesini "yüksek tüketimli"
diye okur, oysa fark tüketimden değil satır sayısından geliyor. İtilen hesap satır sayısını
getirmediği sürece bu ayrım raporda yapılamaz.

İkinci tablo kazancın nereye bağlı olduğunu gösteriyor. İtilen toplulaştırmanın taşıdığı satır
**grup sayısı kadardır**; grup sayısı arttıkça kazanç erir. Üç basamaklı kırılımda oran 3.199 kat,
beş bölgeli kırılımda 1.919 kat, bölge ile basamağın çaprazında 426 kat, abone kırılımında 11
kattır. Son satır tam eşitliği veriyor: abone anahtarıyla toplulaştırma 1.670 değer taşır ve
süzülmüş, iki sütuna daraltılmış ham dilim de 1.670 değer taşır. **Grup sayısı süzülen satır
sayısına eşitlendiğinde itmenin kazancı sıfırlanır** — 835 grup, 835 satır. Bu noktadan sonra ham
dilimi çekmek daha iyidir, çünkü aynı bedelle gelen ham satırlarla başka sorular da cevaplanabilir.

## Özet

- Aynı soru dört itme derecesiyle cevaplandı ve dördü de 17.307,2 m³ verdi; taşınan satır 3.199'dan
  5'e, taşınan değer 19.194'ten 10'a indi ve kazanç 1.919 kat oldu.
- Kalemler ayrışıyor: süzgecin itilmesi satırı 835'e, sütun seçiminin itilmesi değeri 1.670'e,
  toplulaştırmanın itilmesi satırı 5'e indirir.
- İtilen toplam süzgeçten geçen 835 satırı, kaynaktaki 3.199 satırı ve grup başına satır sayısını
  getirmez; bu kalemleri de istemek taşınan değeri 27'ye çıkarır ve oranı 710 kata indirir.
- Merkez bölgesinin 8.752,6 m³'ü 418 satırdan, batının 1.789,1 m³'ü 83 satırdan gelir; ortalamalar
  20,94 ve 21,56 m³'tür ve toplam farkı tüketimden değil satır sayısından doğar.
- İtme kazancı grup sayısına bağlıdır: 3 grupta 3.199 kat, 15 grupta 426 kat, 835 grupta 11 kat;
  grup sayısı süzülen satır sayısına eşitlendiğinde kazanç sıfırlanır.
- İki toplam arasındaki fark sıfır çıksa da eşitlik eşikle sınanır, çünkü kaynağın grup içini hangi
  sırada topladığı arayüzün dışındadır.

## Sonraki Adım

Bu konu beş derste tek bir soruyu izledi: küme belleğe sığmadığında soyutlamanın rahatlığından ne
kalıyor. Cevap her derste araç değiştirerek geldi. Tip seçimi sütunu 47,9 kat küçülttü, parçalama
bellek tepesini 32 kat düşürdü, sütunlu yerleşim okunan değeri 6,8 kat azalttı, dağıtım büyük
kümede 19,7 kata kadar kazandırdı ve hesabı veriye itmek taşınan kaydı 1.919 kat azalttı. Ölçek
sorunu her seferinde **yerleşimi, bölümlemeyi ya da hesabın yapıldığı yeri** değiştirerek çözüldü.

Değişmeyen tek şey dilin kendisiydi. Yirmi derstir aynı ifade biçimi kullanılıyor: döngüler,
atamalar, ara değişkenler ve adım adım kurulan hesaplar. Sonraki konu bu varsayımı sorgular ve
analizi başka türlü ifade eden ortamlara bakar — aynı analizin kaç adımda anlatıldığını, dönüştürme
zincirinin kaç ara değişken tuttuğunu ve bir grafiğin kaç katmanla kurulduğunu sayar. Ölçü yine
aynıdır: soyutlamanın kazandırdığı ve gizlediği.
