import pandera.polars as pa
import warnings
import polars as pl
from pandera.polars import PolarsData
def is_not_null(data: PolarsData) -> pl.LazyFrame:
"""Return a LazyFrame with a single boolean column."""
return data.lazyframe.select(pl.col(data.key).is_not_null())
def mean_less_than(data: PolarsData, threshold=0) -> pl.LazyFrame:
"""Return a LazyFrame with a single boolean column."""
return data.lazyframe.select(pl.col(data.key).mean() < threshold)
df = pl.read_csv('file.csv', separator=',', quote_char='"', infer_schema_length = 100000)
schema = pa.DataFrameSchema({
"ISIN": pa.Column(
str,
checks=[
pa.Check.str_matches(r'^\w{12}$', ignore_na=True,raise_warning=True, title="ISIN pattern check", description="ISIN has to be 12 characters long"),
pa.Check(is_not_null, ignore_na=True,raise_warning=True, title="ISIN null check", description="ISIN cannot be null")
], nullable = True
),
"ID": pa.Column(
str,
checks=[
pa.Check.str_matches(r'^\w{9}$', ignore_na=True,raise_warning=True, title="ID pattern check", description="ID has to be 9 characters long"),
pa.Check(is_not_null, ignore_na=True,raise_warning=True, title="ID null check", description="ID cannot be null")
], nullable = True
),
"PRICE": pa.Column(
float,
checks=[
pa.Check.greater_than_or_equal_to(0, ignore_na=True,raise_warning=True),
pa.Check.less_than_or_equal_to(10000, ignore_na=True,raise_warning=True),
pa.Check.in_range(min_value=0, max_value=10000, include_min=True, include_max=True, ignore_na=True,raise_warning=True),
pa.Check(mean_less_than, threshold=97.5, ignore_na=True,raise_warning=True, title="PRICE MEAN check", description="MEAN(PRICE) has to be less than 0", error="mean above threshold")
], nullable = True
)
})
with warnings.catch_warnings(record=True) as caught_warnings:
warnings.simplefilter("always")
validated_df = df.pipe(schema_with_custom_checks.validate)
for warning in caught_warnings:
print(warning)
Хотя мне удалось запустить его с помощью raise_warning=true и перехватить предупреждающие сообщения, я не смог вернуть строки, которые не прошли проверку.
Я знаю, что в Pandas мне удалось сделать это с помощью некоторых изменений (raise_warning=False и перехвата ошибок схемы):
Можно ли получить недопустимые строки проверки схемы PanderaPolars? Другие вопросы о PanderaPolars: [list] [*]Можно ли получить лямбда-проверки, как в PanderaPandas? [*]Можно ли определить проверку, которая принимает фильтр (например, проверьте столбец A > 100, учитывая, что столбец B = 'box-quantity') [/list] Я начал изучать Pandera, используя фрейм данных Polars. Я написал простой пример схемы ниже: [code]import pandera.polars as pa import warnings import polars as pl from pandera.polars import PolarsData
def is_not_null(data: PolarsData) -> pl.LazyFrame: """Return a LazyFrame with a single boolean column.""" return data.lazyframe.select(pl.col(data.key).is_not_null())
def mean_less_than(data: PolarsData, threshold=0) -> pl.LazyFrame: """Return a LazyFrame with a single boolean column.""" return data.lazyframe.select(pl.col(data.key).mean() < threshold)
schema = pa.DataFrameSchema({ "ISIN": pa.Column( str, checks=[ pa.Check.str_matches(r'^\w{12}$', ignore_na=True,raise_warning=True, title="ISIN pattern check", description="ISIN has to be 12 characters long"), pa.Check(is_not_null, ignore_na=True,raise_warning=True, title="ISIN null check", description="ISIN cannot be null") ], nullable = True ), "ID": pa.Column( str, checks=[ pa.Check.str_matches(r'^\w{9}$', ignore_na=True,raise_warning=True, title="ID pattern check", description="ID has to be 9 characters long"), pa.Check(is_not_null, ignore_na=True,raise_warning=True, title="ID null check", description="ID cannot be null") ], nullable = True ), "PRICE": pa.Column( float, checks=[ pa.Check.greater_than_or_equal_to(0, ignore_na=True,raise_warning=True), pa.Check.less_than_or_equal_to(10000, ignore_na=True,raise_warning=True), pa.Check.in_range(min_value=0, max_value=10000, include_min=True, include_max=True, ignore_na=True,raise_warning=True), pa.Check(mean_less_than, threshold=97.5, ignore_na=True,raise_warning=True, title="PRICE MEAN check", description="MEAN(PRICE) has to be less than 0", error="mean above threshold") ], nullable = True ) })
with warnings.catch_warnings(record=True) as caught_warnings: warnings.simplefilter("always") validated_df = df.pipe(schema_with_custom_checks.validate) for warning in caught_warnings: print(warning)
[/code] Хотя мне удалось запустить его с помощью raise_warning=true и перехватить предупреждающие сообщения, я не смог вернуть строки, которые не прошли проверку. Я знаю, что в Pandas мне удалось сделать это с помощью некоторых изменений (raise_warning=False и перехвата ошибок схемы): [code]import pandera as pa import pandas as pd import warnings
try: schema(df, lazy=True) except pa.errors.SchemaErrors as exc: filtered_df = df[df.index.isin(exc.failure_cases["index"])]
print(f"filtered df:\n{filtered_df}") [/code] Я попытался воспроизвести то же самое с пандами, используя поляры, следующим образом: [code]import pandera.polars as pa import warnings import polars as pl from pandera.polars import PolarsData
def is_not_null(data: PolarsData) -> pl.LazyFrame: """Return a LazyFrame with a single boolean column.""" return data.lazyframe.select(pl.col(data.key).is_not_null())
def mean_less_than(data: PolarsData, threshold=0) -> pl.LazyFrame: """Return a LazyFrame with a single boolean column.""" return data.lazyframe.select(pl.col(data.key).mean() < threshold)
schema = pa.DataFrameSchema({ "ISIN": pa.Column( str, checks=[ pa.Check.str_matches(r'^\w{12}$', ignore_na=True,raise_warning=False, title="ISIN pattern check", description="ISIN has to be 12 characters long"), pa.Check(is_not_null, ignore_na=True,raise_warning=False, title="ISIN null check", description="ISIN cannot be null") ], nullable = True ), "ID": pa.Column( str, checks=[ pa.Check.str_matches(r'^\w{9}$', ignore_na=True,raise_warning=False, title="ID pattern check", description="ID has to be 9 characters long"), pa.Check(is_not_null, ignore_na=True,raise_warning=False, title="ID null check", description="ID cannot be null") ], nullable = True ), "PRICE": pa.Column( float, checks=[ pa.Check.greater_than_or_equal_to(0, ignore_na=True,raise_warning=False), pa.Check.less_than_or_equal_to(10000, ignore_na=True,raise_warning=False), pa.Check.in_range(min_value=0, max_value=10000, include_min=True, include_max=True, ignore_na=True,raise_warning=False), pa.Check(mean_less_than, threshold=97.5, ignore_na=True,raise_warning=False, title="PRICE MEAN check", description="MEAN(PRICE) has to be less than 0", error="mean above threshold") ], nullable = True ) })
try: schema(df, lazy=True) except pa.errors.SchemaErrors as exc: filtered_df = df[df.index.isin(exc.failure_cases["index"])]
print(f"filtered df:\n{filtered_df}") [/code] но я получил AttributeError: объект DataFrame не имеет атрибута index Мой вопрос: можно ли вернуть недопустимые строки с помощью PanderaPolars.>