Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Code Workspaces의 행과 열 필터

작업공간에 데이터를 모두 올리기 전에 행이나 열을 줄이면 메모리 사용량을 줄일 수 있습니다. 압축을 푼 전체 데이터가 메모리에 들어오면 한 번 로드한 뒤 메모리에서 여러 변환을 하는 방식이 효율적일 수 있습니다.

데이터가 크면 push-down 필터 또는 SQL로 필요한 부분을 가져옵니다. 필터 성능은 데이터 규모와 파티션 구성에 영향을 받습니다. 같은 부분집합을 여러 작업공간에서 반복 사용한다면 Spark transform으로 작은 데이터셋을 미리 만들 수 있습니다. Parquet 다운로드는 재사용할 수 있지만 필터는 로드할 때마다 수행합니다.

지원 조건

  • 열 선택은 모든 표 형식 데이터셋에서 사용할 수 있습니다.
  • 행 필터는 Parquet 데이터셋에만 적용합니다. CSV 같은 형식은 열 선택은 지원하지만 이 행 필터 경로는 지원하지 않습니다.
  • Python에서 columns, row_limit 또는 where 필터를 사용하면 format은 arrow, dataframe, pandas 또는 polars여야 하고 mode는 current여야 합니다.
  • 이 필터가 있는 읽기에 lazy-polars 또는 path 출력을 지정하지 않습니다.

복잡한 파일 처리가 필요하면 원본 파일을 다운로드하여 그 형식의 Python/R 라이브러리로 처리할 수 있습니다.

행 수 상한

Python:

from foundry.transforms import Dataset

dogs_subset = Dataset.get("dogs").limit(1000).read_table(format="pandas")

R:

library(foundry)
library(dplyr)

dogs_subset <- Dataset.get("dogs") %>%
  head(1000) %>%
  collect()

limit 또는 head의 상한은 다른 필터보다 먼저 적용됩니다. 따라서 필터 조건을 만족하는 행 1,000개가 반환된다는 의미는 아닙니다.

가상 예제 데이터

dogs 별칭의 Parquet 데이터셋에 다음 행이 있다고 가정합니다.

nameweightcoloragebreed
Bella60Brown4Labrador
Max75Black7German Shepherd
Daisy30White2Poodle
Buddy65Yellow3Labrador
Gizmo18Brown1Pug

열 선택

Python:

from foundry.transforms import Dataset

columns_to_load = ["breed", "age"]
breed_and_age_only = (
    Dataset.get("dogs").select(*columns_to_load).read_table(format="pandas")
)
weight_and_color_only = (
    Dataset.get("dogs").select("weight", "color").read_table(format="pandas")
)

R:

library(foundry)
library(dplyr)

weight_and_color_only <- Dataset.get("dogs") %>%
  select(weight, color) %>%
  collect()

Python 행 필터

Column.get으로 속성을 참조하고 where를 연결합니다.

from foundry.transforms import Dataset, Column

brown_dogs = (
    Dataset.get("dogs")
    .where(Column.get("color") == "Brown")
    .read_table(format="pandas")
)
brown_labradors = (
    Dataset.get("dogs")
    .where(Column.get("color") == "Brown")
    .where(Column.get("breed") == "Labrador")
    .read_table(format="pandas")
)

지원 표현은 다음과 같습니다.

  • 같음: Column.get("color") == "Brown"
  • 다름: Column.get("color") != "Brown" 또는 ~(Column.get("color") == "Brown")
  • 크기 비교: Column.get("age") > 2, >= 2, < 4, <= 4
  • OR: (Column.get("color") == "Brown") | (Column.get("color") == "White")
  • AND: (Column.get("color") == "Brown") & (Column.get("breed") == "Labrador")
  • null 제외: ~Column.get("age").isnull()
  • 목록 포함: Column.get("color").isin(["Brown", "White"])
  • 양끝 포함 범위: Column.get("date_column").between("2024-01-01", "2024-12-31")

마지막 날짜 예는 별도 date_column이 있는 입력을 전제로 합니다. Boolean 조건을 합칠 때는 각 비교식을 괄호로 묶습니다.

R 행 필터

R의 Dataset.get과 dplyr 체인은 collect 전에 지원 필터를 적용합니다. 이름이 같은 다른 패키지 함수와 충돌하지 않도록 foundry::filter를 사용합니다.

library(foundry)
library(dplyr)

brown_dogs <- Dataset.get("dogs") %>%
  foundry::filter(color == "Brown") %>%
  collect()

brown_labradors <- Dataset.get("dogs") %>%
  foundry::filter(color == "Brown") %>%
  foundry::filter(breed == "Labrador") %>%
  collect()

필터 안의 열 이름은 문자열로 감싸지 않습니다. 지원 비교와 결합은 다음과 같습니다.

  • 같음 및 다름: color == "Brown", age == 4, color != "Brown", !(color == "Brown")
  • 크기 비교: age > 2, age >= 2, age < 4, age <= 4
  • OR/AND: color == "Brown" | color == "White", color == "Brown" & breed == "Labrador"
  • 목록 포함: color %in% c("Brown", "White")
  • 결측 제외: !is.na(age)
  • 양끝 포함 범위: between(age, 2, 4)

R에서 collect 전에 select를 사용하면 filter 절이 사용하는 모든 열도 선택에 포함해야 합니다.

행과 열을 함께 제한

다음 예는 weight가 62보다 크고 color가 Brown인 행에서 name, breed와 color를 남깁니다. 위 가상 데이터에서는 조건을 만족하는 행이 없으므로 빈 결과가 맞습니다.

Python:

from foundry.transforms import Dataset, Column

heavy_brown_dogs = (
    Dataset.get("dogs")
    .where(Column.get("weight") > 62)
    .where(Column.get("color") == "Brown")
    .select("name", "breed", "color")
    .read_table(format="arrow")
    .to_pandas()
)

R에서는 원격 필터에 필요한 weight를 collect까지 유지한 뒤 로컬 결과에서 최종 열을 선택합니다.

library(foundry)
library(dplyr)

heavy_brown_dogs <- Dataset.get("dogs") %>%
  foundry::filter(weight > 62) %>%
  foundry::filter(color == "Brown") %>%
  select(name, breed, color, weight) %>%
  collect() %>%
  select(name, breed, color)

Arrow로 가져온 뒤 추가 변환

단순 조건은 먼저 적용하고, group_by 같은 추가 연산은 Arrow Table로 가져온 뒤 수행할 수 있습니다. 다음 예는 age가 2보다 큰 개를 품종별로 세는 실제 집계입니다.

library(foundry)
library(dplyr)

counts_by_breed <- Dataset.get("dogs") %>%
  foundry::filter(age > 2) %>%
  collect(as_data_frame = FALSE) %>%
  group_by(breed) %>%
  summarise(count = n()) %>%
  collect()

Arrow 단계의 처리와 Foundry 입력에 적용하는 push-down 필터는 실행 위치가 다르므로 어느 단계에서 데이터가 작업공간으로 들어오는지 구분합니다.