CollectionExpr merepresentasikan set data dua dimensi dalam PyODPS DataFrame API, setara dengan tabel MaxCompute atau spreadsheet. Objek DataFrame juga merupakan objek CollectionExpr yang mendukung operasi kolom, penyaringan data, dan transformasi data.
Prasyarat
Sebelum memulai, pastikan Anda telah memiliki:
-
Tabel bernama
pyodps_iris. Untuk informasi lebih lanjut, lihat bagian "Pemrosesan data DataFrame" dalam Getting started. -
Objek DataFrame. Untuk informasi lebih lanjut, lihat bagian "Buat objek DataFrame dari tabel MaxCompute" dalam Create a DataFrame object.
Ambil tipe kolom
Gunakan atribut dtypes untuk mendapatkan tipe semua kolom dalam CollectionExpr. Ini mengembalikan tipe Schema.
print(iris.dtypes)
Output:
odps.Schema {
sepallength float64
sepalwidth float64
petallength float64
petalwidth float64
name string
}
Pilih, tambah, dan hapus kolom
Tabel berikut menunjukkan sintaks yang digunakan berdasarkan tujuan Anda:
| Tujuan | Sintaks yang direkomendasikan | Versi PyODPS |
|---|---|---|
| Pilih kolom tertentu | expr[col1, col2] |
Semua versi |
| Kecualikan kolom | exclude(col1, col2) |
Semua versi |
| Tambahkan kolom terhitung | iris['new_col'] = expr |
0.7.2+ |
| Timpa kolom yang sudah ada | iris['col'] = new_expr |
0.7.2+ |
| Hapus kolom | del iris['col'] |
0.7.2+ |
| Pembaruan kolom bersyarat | iris[condition, 'col'] = expr |
0.7.2+ |
| Tambahkan kolom konstan | iris['col'] = value |
0.7.12+ |
| Ubah nama saat memilih | select(col, new_name=expr) |
Semua versi |
Pilih kolom
Gunakan expr[columns] untuk memilih kolom tertentu dari CollectionExpr.
print(iris['name', 'sepallength'].head(5))
Output:
name sepallength
0 Iris-setosa 4.9
1 Iris-setosa 4.7
2 Iris-setosa 4.6
3 Iris-setosa 5.0
4 Iris-setosa 5.4
Untuk memilih satu kolom dan mengembalikan Collection (bukan Sequence), tambahkan koma di akhir atau gunakan kurung siku ganda:iris[iris.sepallength,]atauiris[[iris.sepallength]]. Tanpa ini, objek Sequence akan dikembalikan.
Hapus kolom
Menggunakan `exclude` (semua versi PyODPS):
print(iris.exclude('sepallength', 'petallength')[:5].head(5))
Output:
sepalwidth petalwidth name
0 3.0 0.2 Iris-setosa
1 3.2 0.2 Iris-setosa
2 3.1 0.2 Iris-setosa
3 3.6 0.2 Iris-setosa
4 3.9 0.4 Iris-setosa
Menggunakan `del` (PyODPS 0.7.2+):
del iris['sepallength']
del iris['petallength']
print(iris[:5].head(5))
Output:
sepalwidth petalwidth name
0 3.0 0.2 Iris-setosa
1 3.2 0.2 Iris-setosa
2 3.1 0.2 Iris-setosa
3 3.6 0.2 Iris-setosa
4 3.9 0.4 Iris-setosa
Tambahkan kolom
Menggunakan sintaks penugasan (PyODPS 0.7.2+, direkomendasikan):
iris['sepalwidthplus1'] = iris.sepalwidth + 1
print(iris.head(5))
Output:
sepallength sepalwidth petallength petalwidth name \
0 4.9 3.0 1.4 0.2 Iris-setosa
1 4.7 3.2 1.3 0.2 Iris-setosa
2 4.6 3.1 1.5 0.2 Iris-setosa
3 5.0 3.6 1.4 0.2 Iris-setosa
4 5.4 3.9 1.7 0.4 Iris-setosa
sepalwidthplus1
0 4.0
1 4.2
2 4.1
3 4.6
4 4.9
Menggunakan `expr[expr, new_sequence]` (semua versi): Membuat Collection baru dengan kolom tambahan yang ditambahkan. Jika kolom baru memiliki nama yang sama dengan kolom yang sudah ada, ubah namanya untuk menghindari konflik.
print(iris[iris, (iris.sepalwidth + 1).rename('sepalwidthplus1')].head(5))
Output:
sepallength sepalwidth petallength petalwidth name \
0 4.9 3.0 1.4 0.2 Iris-setosa
1 4.7 3.2 1.3 0.2 Iris-setosa
2 4.6 3.1 1.5 0.2 Iris-setosa
3 5.0 3.6 1.4 0.2 Iris-setosa
4 5.4 3.9 1.7 0.4 Iris-setosa
sepalwidthplus1
0 4.0
1 4.2
2 4.1
3 4.6
4 4.9
Tambahkan dan hapus kolom secara simultan
Timpa kolom yang sudah ada (PyODPS 0.7.2+):
iris['sepalwidth'] = iris.sepalwidth * 2
print(iris.head(5))
Output:
sepallength sepalwidth petallength petalwidth name
0 4.9 6.0 1.4 0.2 Iris-setosa
1 4.7 6.4 1.3 0.2 Iris-setosa
2 4.6 6.2 1.5 0.2 Iris-setosa
3 5.0 7.2 1.4 0.2 Iris-setosa
4 5.4 7.8 1.7 0.4 Iris-setosa
Menggunakan `exclude` dengan kolom baru (semua versi): Mengecualikan kolom asli dan menambahkan versi hasil transformasi, sehingga tidak perlu mengubah nama.
print(iris[iris.exclude('sepalwidth'), iris.sepalwidth * 2].head(5))
Output:
sepallength petallength petalwidth name sepalwidth
0 4.9 1.4 0.2 Iris-setosa 6.0
1 4.7 1.3 0.2 Iris-setosa 6.4
2 4.6 1.5 0.2 Iris-setosa 6.2
3 5.0 1.4 0.2 Iris-setosa 7.2
4 5.4 1.7 0.4 Iris-setosa 7.8
Menggunakan `select` (semua versi): Mirip dengan exclude dengan kolom baru, tetapi memungkinkan Anda mengubah nama hasilnya dalam satu langkah menggunakan argumen kata kunci.
print(iris.select('name', sepalwidthminus1=iris.sepalwidth - 1).head(5))
Output:
name sepalwidthminus1
0 Iris-setosa 2.0
1 Iris-setosa 2.2
2 Iris-setosa 2.1
3 Iris-setosa 2.6
4 Iris-setosa 2.9
Menggunakan ekspresi lambda: Teruskan lambda yang menerima hasil operasi sebelumnya sebagai parameter. PyODPS mengevaluasi lambda tersebut dan menggantinya dengan kolom yang valid dari Collection tersebut.
print(iris['name', 'petallength'][[lambda x: x.name]].head(5))
Output:
name
0 Iris-setosa
1 Iris-setosa
2 Iris-setosa
3 Iris-setosa
4 Iris-setosa
Pembaruan kolom bersyarat (PyODPS 0.7.2+): Perbarui kolom hanya untuk baris yang memenuhi kondisi tertentu.
iris[iris.sepallength > 5.0, 'sepalwidth'] = iris.sepalwidth * 2
print(iris.head(5))
Output:
sepallength sepalwidth petallength petalwidth name
0 4.9 3.0 1.4 0.2 Iris-setosa
1 4.7 3.2 1.3 0.2 Iris-setosa
2 4.6 3.1 1.5 0.2 Iris-setosa
3 5.0 3.6 1.4 0.2 Iris-setosa
4 5.4 7.8 1.7 0.4 Iris-setosa
Perkenalkan konstanta dan bilangan acak
Tambahkan kolom konstan
Sintaks sederhana (PyODPS 0.7.12+, direkomendasikan): Tetapkan nilai literal langsung ke kolom baru.
iris['id'] = 1
print(iris.head(5))
Output:
sepallength sepalwidth petallength petalwidth name id
0 4.9 3.0 1.4 0.2 Iris-setosa 1
1 4.7 3.2 1.3 0.2 Iris-setosa 1
2 4.6 3.1 1.5 0.2 Iris-setosa 1
3 5.0 3.6 1.4 0.2 Iris-setosa 1
4 5.4 3.9 1.7 0.4 Iris-setosa 1
Sintaks sederhana tidak dapat melakukan inferensi tipe nilai null secara otomatis. Untuk menambahkan kolom null, gunakan NullScalar dengan tipe eksplisit.from odps.df import NullScalar
iris['null_col'] = NullScalar('float')
print(iris.head(5))
Output:
sepallength sepalwidth petallength petalwidth name null_col
0 4.9 3.0 1.4 0.2 Iris-setosa None
1 4.7 3.2 1.3 0.2 Iris-setosa None
2 4.6 3.1 1.5 0.2 Iris-setosa None
3 5.0 3.6 1.4 0.2 Iris-setosa None
4 5.4 3.9 1.7 0.4 Iris-setosa None
Menggunakan `Scalar` (semua versi): Bungkus konstanta dengan Scalar dan tentukan nama kolom secara manual.
from odps.df import Scalar
print(iris[iris, Scalar(1).rename('id')][:5].head(5))
Output:
sepallength sepalwidth petallength petalwidth name id
0 4.9 3.0 1.4 0.2 Iris-setosa 1
1 4.7 3.2 1.3 0.2 Iris-setosa 1
2 4.6 3.1 1.5 0.2 Iris-setosa 1
3 5.0 3.6 1.4 0.2 Iris-setosa 1
4 5.4 3.9 1.7 0.4 Iris-setosa 1
Untuk menambahkan kolom null dengan tipe eksplisit:
from odps.df import NullScalar
print(iris[iris, NullScalar('float').rename('fid')][:5].head(5))
Output:
sepallength sepalwidth petallength petalwidth name fid
0 4.9 3.0 1.4 0.2 Iris-setosa None
1 4.7 3.2 1.3 0.2 Iris-setosa None
2 4.6 3.1 1.5 0.2 Iris-setosa None
3 5.0 3.6 1.4 0.2 Iris-setosa None
4 5.4 3.9 1.7 0.4 Iris-setosa None
Tambahkan kolom bilangan acak
Gunakan RandomScalar untuk menambahkan kolom berisi nilai FLOAT acak dalam rentang 0–1, dengan nilai unik per baris. Parameter opsionalnya adalah seed acak.
from odps.df import RandomScalar
iris[iris, RandomScalar().rename('rand_val')][:5]
Output:
sepallength sepalwidth petallength petalwidth name rand_val
0 4.9 3.0 1.4 0.2 Iris-setosa 0.000471
1 4.7 3.2 1.3 0.2 Iris-setosa 0.799520
2 4.6 3.1 1.5 0.2 Iris-setosa 0.834609
3 5.0 3.6 1.4 0.2 Iris-setosa 0.106921
4 5.4 3.9 1.7 0.4 Iris-setosa 0.763442
Filter data
Filter baris menggunakan operator standar, metode filter, metode query, atau ekspresi lambda.
Dalam ekspresi filter standar, gunakan&untuk AND dan|untuk OR — kata kunci Pythonanddanortidak didukung. Metodequerymenerima keduanya.
Filter berdasarkan kondisi:
print(iris[iris.sepallength > 5].head(5))
Output:
sepallength sepalwidth petallength petalwidth name
0 5.4 3.9 1.7 0.4 Iris-setosa
1 5.4 3.7 1.5 0.2 Iris-setosa
2 5.8 4.0 1.2 0.2 Iris-setosa
3 5.7 4.4 1.5 0.4 Iris-setosa
4 5.4 3.9 1.3 0.4 Iris-setosa
AND (`&`):
print(iris[(iris.sepallength < 5) & (iris['petallength'] > 1.5)].head(5))
Output:
sepallength sepalwidth petallength petalwidth name
0 4.8 3.4 1.6 0.2 Iris-setosa
1 4.8 3.4 1.9 0.2 Iris-setosa
2 4.7 3.2 1.6 0.2 Iris-setosa
3 4.8 3.1 1.6 0.2 Iris-setosa
4 4.9 2.4 3.3 1.0 Iris-versicolor
OR (`|`):
print(iris[(iris.sepalwidth < 2.5) | (iris.sepalwidth > 4)].head(5))
Output:
sepallength sepalwidth petallength petalwidth name
0 5.7 4.4 1.5 0.4 Iris-setosa
1 5.2 4.1 1.5 0.1 Iris-setosa
2 5.5 4.2 1.4 0.2 Iris-setosa
3 4.5 2.3 1.3 0.3 Iris-setosa
4 5.5 2.3 4.0 1.3 Iris-versicolor
NOT (`~`):
print(iris[~(iris.sepalwidth > 3)].head(5))
Output:
sepallength sepalwidth petallength petalwidth name
0 4.9 3.0 1.4 0.2 Iris-setosa
1 4.4 2.9 1.4 0.2 Iris-setosa
2 4.8 3.0 1.4 0.1 Iris-setosa
3 4.3 3.0 1.1 0.1 Iris-setosa
4 5.0 3.0 1.6 0.2 Iris-setosa
Metode `filter` dengan beberapa kondisi: Meneruskan beberapa argumen ke filter setara dengan menggabungkannya dengan &.
print(iris.filter(iris.sepalwidth > 3.5, iris.sepalwidth < 4).head(5))
Output:
sepallength sepalwidth petallength petalwidth name
0 5.0 3.6 1.4 0.2 Iris-setosa
1 5.4 3.9 1.7 0.4 Iris-setosa
2 5.4 3.7 1.5 0.2 Iris-setosa
3 5.4 3.9 1.3 0.4 Iris-setosa
4 5.7 3.8 1.7 0.3 Iris-setosa
Ekspresi lambda untuk operasi berantai:
print(iris[iris.sepalwidth > 3.8]['name', lambda x: x.sepallength + 1].head(5))
Output:
name sepallength
0 Iris-setosa 6.4
1 Iris-setosa 6.8
2 Iris-setosa 6.7
3 Iris-setosa 6.4
4 Iris-setosa 6.2
Kolom BOOLEAN sebagai filter: Saat Collection berisi kolom BOOLEAN, gunakan kolom tersebut langsung sebagai kondisi filter.
# Periksa skema
print(df.dtypes)
# odps.Schema {
# a boolean
# b int64
# }
# Filter menggunakan kolom boolean
print(df[df.a])
# a b
# 0 True 1
# 1 True 3
Contoh berikut menunjukkan perbedaan antara mengambil satu kolom dan menggunakannya sebagai filter:
df[df.a, ] # Ambil Collection satu kolom
df[[df.a]] # Ambil Collection satu kolom
df.select(df.a) # Ambil Collection satu kolom secara eksplisit
df[df.a] # Gunakan kolom a (BOOLEAN) sebagai kondisi filter
df.a # Ambil kolom dari Collection
df['a'] # Ambil kolom dari Collection
Filter dengan query
Metode query menerima kondisi filter sebagai ekspresi string, mirip dengan Pandas. Referensikan nama kolom secara langsung dalam string; awali variabel lokal dengan @.
print(iris.query("(sepallength < 5) and (petallength > 1.5)").head(5))
Output:
sepallength sepalwidth petallength petalwidth name
0 4.8 3.4 1.6 0.2 Iris-setosa
1 4.8 3.4 1.9 0.2 Iris-setosa
2 4.7 3.2 1.6 0.2 Iris-setosa
3 4.8 3.1 1.6 0.2 Iris-setosa
4 4.9 2.4 3.3 1.0 Iris-versicolor
Gunakan @ untuk mereferensikan variabel lokal di dalam string query:
var = 4
print(iris.query("(sepalwidth < 2.5) | (sepalwidth > @var)").head(5))
Output:
sepallength sepalwidth petallength petalwidth name
0 5.7 4.4 1.5 0.4 Iris-setosa
1 5.2 4.1 1.5 0.1 Iris-setosa
2 5.5 4.2 1.4 0.2 Iris-setosa
3 4.5 2.3 1.3 0.3 Iris-setosa
4 5.5 2.3 4.0 1.3 Iris-versicolor
Metode query mendukung sintaks berikut:
| Sintaks | Deskripsi | |
|---|---|---|
| name | Nama kolom (tanpa awalan @). Gunakan @variable untuk mereferensikan variabel Python lokal. |
|
| operator | +, -, *, /, //, %, **, ==, !=, <, <=, >, >=, in, not in |
|
| bool | DAN: & atau and. ATAU: ` | or or`. |
| attribute | Atribut objek | |
| index, slice, subscript | Operasi slice |
Ubah kolom menjadi baris
Gunakan explode untuk memperluas kolom LIST atau MAP menjadi beberapa baris. Anda juga dapat menggunakan metode apply untuk output multi-baris. Anda dapat melakukan explode pada satu atau beberapa kolom secara simultan. Jika satu baris input tidak menghasilkan output (misalnya, daftar kosong), baris tersebut dikecualikan secara default. Atur keep_nulls=True untuk menyimpan baris tersebut dengan nilai null.
Untuk informasi lebih lanjut tentang cara menggunakan explode untuk output multi-baris, lihat bagian "Operasi terkait Collection" dalam Column operations.
Data contoh:
print(df)
# id a b
# 0 1 [a1, b1] [a2, b2, c2]
# 1 2 [c1] [d2, e2]
Explode satu kolom, pertahankan kolom lainnya:
print(df[df.id, df.a.explode(), df.b])
Output:
id a b
0 1 a1 [a2, b2, c2]
1 1 b1 [a2, b2, c2]
2 2 c1 [d2, e2]
Memecah dua kolom secara bersamaan:
print(df[df.id, df.a.explode(), df.b.explode()])
Output:
id a b
0 1 a1 a2
1 1 a1 b2
2 1 a1 c2
3 1 b1 a2
4 1 b1 b2
5 1 b1 c2
6 2 c1 d2
7 2 c1 e2
`keep_nulls=True` — pertahankan baris dengan input kosong:
print(df)
# id a
# 0 1 [a1, b1]
# 1 2 []
# Tanpa keep_nulls: baris 2 dihapus
print(df[df.id, df.a.explode()])
# id a
# 0 1 a1
# 1 1 b1
# Dengan keep_nulls=True: baris 2 dipertahankan dengan nilai null
print(df[df.id, df.a.explode(keep_nulls=True)])
# id a
# 0 1 a1
# 1 1 b1
# 2 2 None
Batasan output
Batasi jumlah baris yang dikembalikan menggunakan sintaks slice atau metode limit.
Sintaks slice:
print(iris[:3].execute())
Output:
sepallength sepalwidth petallength petalwidth name
0 4.9 3.0 1.4 0.2 Iris-setosa
1 4.7 3.2 1.3 0.2 Iris-setosa
2 4.6 3.1 1.5 0.2 Iris-setosa
Metode `limit`:
print(iris.limit(3).execute())
Output:
sepallength sepalwidth petallength petalwidth name
0 4.9 3.0 1.4 0.2 Iris-setosa
1 4.7 3.2 1.3 0.2 Iris-setosa
2 4.6 3.1 1.5 0.2 Iris-setosa
Di backend MaxCompute SQL, operasi slice tidak mendukungstartataustep— hanyalimityang didukung. Operasi slice hanya berlaku untuk objek Collection, bukan objek Sequence.