Polars - 04 Veri Tipleri ve Yapılar
Paz 28 Haziran 2026Veri Tipleri ve Yapılar
Veri Tipleri
Polars, genel olarak aşağıdaki kategorilere ayrılan çeşitli veri tiplerini destekler:
- Numeric veri tipleri: signed integer, unsigned integer, floating point sayılar ve decimal'lar.
- Nested veri tipleri: list, struct ve array'ler.
- Temporal: date, datetime, time ve time delta'lar.
- Diğer: string, binary veri, Boolean, categorical, enum ve object'ler.
Tüm tipler, özel null değeri ile temsil edilen eksik değerleri destekler. Bu, floating point veri tiplerindeki özel NaN değeri ile karıştırılmamalıdır; daha fazla bilgi için floating point sayılar bölümüne bakın.
Tüm desteklenen veri tiplerinin tam listesini ek bölümünde bulabilirsiniz.
Seriler (Series)
Polars tarafından sağlanan temel veri yapıları seriler (series) ve VeriÇerçevesi (dataframe)'dir. Bir seri, 1-boyutlu homojen bir veri yapısıdır. "Homojen" ile kastettiğimiz, bir seri içindeki tüm elemanların aynı veri tipine sahip olmasıdır. Aşağıdaki kod parçacığı, adlandırılmış bir seri'nin nasıl oluşturulacağını gösterir:
Python
Series
import polars as pl
s = pl.Series("ints", [1, 2, 3, 4, 5])
print(s)
Rust
use polars::prelude::*;
let s = Series::new("ints".into(), &[1, 2, 3, 4, 5]);
println!("{s}");
shape: (5,)
Series: 'ints' [i64]
[
1
2
3
4
5
]
Bir seri oluştururken, Polars veri tipini sağladığınız değerlerden çıkarım (inference) yapar. Çıkarım mekanizmasını geçersiz kılmak için somut bir veri tipi belirtebilirsiniz:
Python
s1 = pl.Series("ints", [1, 2, 3, 4, 5])
s2 = pl.Series("uints", [1, 2, 3, 4, 5], dtype=pl.UInt64)
print(s1.dtype, s2.dtype)
Rust
let s1 = Series::new("ints".into(), &[1, 2, 3, 4, 5]);
let s2 = Series::new("uints".into(), &[1, 2, 3, 4, 5])
.cast(&DataType::UInt64)
.unwrap();
println!("{} {}", s1.dtype(), s2.dtype());
Int64 UInt64
Veri Çerçevesi (Dataframe)
VeriÇerçevesi (Dataframe), benzersiz adlandırılmış seri'ler içeren 2-boyutlu heterojen bir veri yapısıdır. Verilerinizi bir dataframe'de tutarak, verilerinizi manipüle eden sorgular yazmak için Polars API'sini kullanabilirsiniz. Bunu, daha sonra ele alacağımız context'ler ve expression'lar aracılığıyla yapabileceksiniz.
Aşağıdaki kod parçacığı, bir sözlükten (dictionary) dataframe'in nasıl oluşturulacağını gösterir:
Python
from datetime import date
df = pl.DataFrame(
{
"name": ["Alice Archer", "Ben Brown", "Chloe Cooper", "Daniel Donovan"],
"birthdate": [
date(1997, 1, 10),
date(1985, 2, 15),
date(1983, 3, 22),
date(1981, 4, 30),
],
"weight": [57.9, 72.5, 53.6, 83.1], # (kg)
"height": [1.56, 1.77, 1.65, 1.75], # (m)
}
)
print(df)
Rust
use chrono::prelude::*;
let df: DataFrame = df!(
"name" => ["Alice Archer", "Ben Brown", "Chloe Cooper", "Daniel Donovan"],
"birthdate" => [
NaiveDate::from_ymd_opt(1997, 1, 10).unwrap(),
NaiveDate::from_ymd_opt(1985, 2, 15).unwrap(),
NaiveDate::from_ymd_opt(1983, 3, 22).unwrap(),
NaiveDate::from_ymd_opt(1981, 4, 30).unwrap(),
],
"weight" => [57.9, 72.5, 53.6, 83.1], // (kg)
"height" => [1.56, 1.77, 1.65, 1.75], // (m)
)
.unwrap();
println!("{df}");
shape: (4, 4)
┌────────────────┬────────────┬────────┬────────┐
│ name ┆ birthdate ┆ weight ┆ height │
│ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ date ┆ f64 ┆ f64 │
╞════════════════╪════════════╪════════╪════════╡
│ Alice Archer ┆ 1997-01-10 ┆ 57.9 ┆ 1.56 │
│ Ben Brown ┆ 1985-02-15 ┆ 72.5 ┆ 1.77 │
│ Chloe Cooper ┆ 1983-03-22 ┆ 53.6 ┆ 1.65 │
│ Daniel Donovan ┆ 1981-04-30 ┆ 83.1 ┆ 1.75 │
└────────────────┴────────────┴────────┴────────┘
VeriÇerçevesi’ni (Dataframe'i) İnceleme
Bu alt bölümde, bir dataframe'i hızlıca incelemek için bazı kullanışlı metotlar göstereceğiz.
Head
head fonksiyonu bir dataframe'in ilk satırlarını gösterir. Varsayılan olarak ilk 5 satırı alırsınız ancak istediğiniz satır sayısını da belirtebilirsiniz:
Python
print(df.head(3))
Rust
let df_head = df.head(Some(3));
println!("{df_head}");
shape: (3, 4)
┌──────────────┬────────────┬────────┬────────┐
│ name ┆ birthdate ┆ weight ┆ height │
│ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ date ┆ f64 ┆ f64 │
╞══════════════╪════════════╪════════╪════════╡
│ Alice Archer ┆ 1997-01-10 ┆ 57.9 ┆ 1.56 │
│ Ben Brown ┆ 1985-02-15 ┆ 72.5 ┆ 1.77 │
│ Chloe Cooper ┆ 1983-03-22 ┆ 53.6 ┆ 1.65 │
└──────────────┴────────────┴────────┴────────┘
Glimpse
glimpse fonksiyonu, bir dataframe'in ilk birkaç satırının değerlerini gösteren başka bir fonksiyondur, ancak çıktıyı head'den farklı biçimlendirir. Burada, çıktının her satırı tek bir sütuna karşılık gelir ve daha geniş dataframe'leri incelemeyi kolaylaştırır:
Python
print(df.glimpse(return_type="string"))
Rows: 4
Columns: 4
$ name <str> 'Alice Archer', 'Ben Brown', 'Chloe Cooper', 'Daniel Donovan'
$ birthdate <date> 1997-01-10, 1985-02-15, 1983-03-22, 1981-04-30
$ weight <f64> 57.9, 72.5, 53.6, 83.1
$ height <f64> 1.56, 1.77, 1.65, 1.75
Bilgi:
glimpseyalnızca Python kullanıcıları için kullanılabilir.
Tail
tail fonksiyonu bir dataframe'in son satırlarını gösterir. Varsayılan olarak son 5 satırı alırsınız ancak head'e benzer şekilde istediğiniz satır sayısını da belirtebilirsiniz:
Python
print(df.tail(3))
Rust
let df_tail = df.tail(Some(3));
println!("{df_tail}");
shape: (3, 4)
┌────────────────┬────────────┬────────┬────────┐
│ name ┆ birthdate ┆ weight ┆ height │
│ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ date ┆ f64 ┆ f64 │
╞════════════════╪════════════╪════════╪════════╡
│ Ben Brown ┆ 1985-02-15 ┆ 72.5 ┆ 1.77 │
│ Chloe Cooper ┆ 1983-03-22 ┆ 53.6 ┆ 1.65 │
│ Daniel Donovan ┆ 1981-04-30 ┆ 83.1 ┆ 1.75 │
└────────────────┴────────────┴────────┴────────┘
Sample
Dataframe'inizin ilk veya son satırlarının verilerinizi temsil etmediğini düşünüyorsanız, DataFrame'den rastgele seçilmiş belirli sayıda satır almak için sample kullanabilirsiniz. Satırların, dataframe'de göründükleri sırayla döndürülmeyebileceğini unutmayın:
Python
sample
pl.set_random_seed(42) # Tekrarlanabilirlik için.
print(df.sample(2))
Rust
sample_n
let n = Series::new("".into(), &[2]);
let sampled_df = df.sample_n(&n, false, false, None).unwrap();
println!("{sampled_df}");
shape: (2, 4)
┌────────────────┬────────────┬────────┬────────┐
│ name ┆ birthdate ┆ weight ┆ height │
│ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ date ┆ f64 ┆ f64 │
╞════════════════╪════════════╪════════╪════════╡
│ Alice Archer ┆ 1997-01-10 ┆ 57.9 ┆ 1.56 │
│ Daniel Donovan ┆ 1981-04-30 ┆ 83.1 ┆ 1.75 │
└────────────────┴────────────┴────────┴────────┘
Describe
Dataframe'inizin tüm sütunları için özet istatistikler hesaplamak üzere describe kullanabilirsiniz:
Python
print(df.describe())
Rust
// Rust'ta mevcut değil
shape: (9, 5)
┌────────────┬────────────────┬─────────────────────┬───────────┬──────────┐
│ statistic ┆ name ┆ birthdate ┆ weight ┆ height │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ str ┆ str ┆ f64 ┆ f64 │
╞════════════╪════════════════╪═════════════════════╪═══════════╪══════════╡
│ count ┆ 4 ┆ 4 ┆ 4.0 ┆ 4.0 │
│ null_count ┆ 0 ┆ 0 ┆ 0.0 ┆ 0.0 │
│ mean ┆ null ┆ 1986-09-04 00:00:00 ┆ 66.775 ┆ 1.6825 │
│ std ┆ null ┆ null ┆ 13.560082 ┆ 0.097082 │
│ min ┆ Alice Archer ┆ 1981-04-30 ┆ 53.6 ┆ 1.56 │
│ 25% ┆ null ┆ 1983-03-22 ┆ 57.9 ┆ 1.65 │
│ 50% ┆ null ┆ 1985-02-15 ┆ 72.5 ┆ 1.75 │
│ 75% ┆ null ┆ 1985-02-15 ┆ 72.5 ┆ 1.75 │
│ max ┆ Daniel Donovan ┆ 1997-01-10 ┆ 83.1 ┆ 1.77 │
└────────────┴────────────────┴─────────────────────┴───────────┴──────────┘
Schema
Verilerden bahsederken (bir dataframe veya başka bir yapıda) onun schema'sına (şemasına) atıfta bulunabiliriz. Schema, sütun veya series adlarının, aynı sütun veya series'lerin veri tiplerine olan eşlemesidir (mapping).
Bir dataframe'in schema'sını schema ile kontrol edebilirsiniz:
Python
print(df.schema)
Rust
println!("{:?}", df.schema());
Schema({'name': String, 'birthdate': Date, 'weight': Float64, 'height': Float64})
Seri'lerde olduğu gibi, Polars bir dataframe oluştururken schema'yı çıkarım (inference) yoluyla belirler ancak gerektiğinde bu çıkarım sistemini geçersiz kılabilirsiniz.
Python'da, sütun adlarını veri tiplerine eşleyen bir sözlük kullanarak açık bir schema belirtebilirsiniz. Belirli bir sütun için çıkarımı geçersiz kılmak istemiyorsanız None değerini kullanabilirsiniz:
df = pl.DataFrame(
{
"name": ["Alice", "Ben", "Chloe", "Daniel"],
"age": [27, 39, 41, 43],
},
schema={"name": None, "age": pl.UInt8},
)
print(df)
shape: (4, 2)
┌────────┬─────┐
│ name ┆ age │
│ --- ┆ --- │
│ str ┆ u8 │
╞════════╪═════╡
│ Alice ┆ 27 │
│ Ben ┆ 39 │
│ Chloe ┆ 41 │
│ Daniel ┆ 43 │
└────────┴─────┘
Yalnızca bazı sütunların çıkarımını geçersiz kılmanız gerekiyorsa, schema_overrides parametresi genellikle daha kullanışlıdır çünkü çıkarımını geçersiz kılmak istemediğiniz sütunları atlamanıza izin verir:
df = pl.DataFrame(
{
"name": ["Alice", "Ben", "Chloe", "Daniel"],
"age": [27, 39, 41, 43],
},
schema_overrides={"age": pl.UInt8},
)
print(df)
shape: (4, 2)
┌────────┬─────┐
│ name ┆ age │
│ --- ┆ --- │
│ str ┆ u8 │
╞════════╪═════╡
│ Alice ┆ 27 │
│ Ben ┆ 39 │
│ Chloe ┆ 41 │
│ Daniel ┆ 43 │
└────────┴─────┘
Veri Tipleri İç Yapısı
Polars, veri yönelimi için Arrow Columnar Format kullanır. Bu spesifikasyonu takip etmek, Polars'ın Arrow spesifikasyonunu kullanan diğer araçlarla çok az ek yük ile veya hiç ek yük olmadan veri aktarmasına olanak tanır.
Polars, performansının büyük kısmını sorgu motorundan, sorgu planlarınız üzerinde yaptığı optimizasyonlardan ve expression'larınızı çalıştırırken kullandığı paralelleştirmeden alır.
Floating Point Sayılar
Polars, Float32 ve Float64 için genel olarak IEEE 754 floating point standardını takip eder, ancak bazı istisnalar vardır:
- Herhangi bir
NaN, diğer herhangi birNaNile eşit olarak karşılaştırılır veNaNolmayan herhangi bir değerden büyüktür. - İşlemler, sıfırın veya
NaN'in işareti veyaNaNdeğerlerinin yükü (payload) konusunda belirli bir davranış garanti etmez. Bu yalnızca aritmetik işlemlerle sınırlı değildir; örneğin, bir sıralama veyagroup-byişlemi, verimli eşitlik kontrolleri için tüm sıfırları +0'a ve tümNaN'leri yüksüz pozitif birNaN'e kanonikleştirebilir.
Polars, floating point hesaplamalar için her zaman makul ölçüde doğru sonuçlar sağlamaya çalışır ancak aksi belirtilmedikçe hata konusunda garanti vermez. Genel olarak, %100 doğru sonuçlar elde etmek aşırı maliyetlidir (64-bit float'lardan çok daha büyük dahili temsiller gerektirir) ve bu nedenle her zaman bir miktar hata beklenmelidir.
Ek: Tüm Veri Tipleri Tablosu
| Tip(ler) | Detaylar |
|---|---|
Boolean |
Bit bazında verimli şekilde paketlenmiş Boolean tipi. |
Int8, Int16, Int32, Int64, Int128 |
Değişken hassasiyetli işaretli tamsayı (signed integer) tipleri. |
UInt8, UInt16, UInt32, UInt64, UInt128 |
Değişken hassasiyetli işaretsiz tamsayı (unsigned integer) tipleri. |
Float16, Float32, Float64 |
Değişken hassasiyetli işaretli ondalıklı (signed floating point) sayılar. |
Decimal |
İsteğe bağlı hassasiyet ve negatif olmayan skalaya sahip Decimal 128-bit tipi. Ondalık'larınızın ve üzerinde yaptığınız işlemlerin hassasiyeti üzerinde ince ayar yapmanız gerekiyorsa kullanın. |
String |
Değişken uzunlukta UTF-8 kodlu dize (string) verisi, genellikle insan tarafından okunabilir. |
Binary |
Rasgele, değişken uzunlukta ham binary veri depolar. |
Date |
Bir takvim tarihini temsil eder. |
Time |
Bir günün saatini temsil eder. |
Datetime |
Bir takvim tarihini ve günün saatini temsil eder. |
Duration |
Bir zaman süresini temsil eder. |
Array |
Seri başına bilinen, sabit şekle sahip array'ler; numpy array'lerine benzer. |
List |
Değişken uzunlukta homojen 1D kap. |
Object |
Rasgele Python nesnelerini sarar. |
Categorical |
Kategorilerin çalışma zamanında çıkarıldığı verimli dize (string) veri kodlaması. |
Enum |
Önceden belirlenmiş bir dizi dize (string) kategorisinin verimli sıralı kodlaması. |
Struct |
Birden fazla alanı depolayabilen bileşik ürün tipi. |
Null |
Null değerleri temsil eder. |