- pandas.DataFrame.isna#
- Как проверить данные во фрейме Pandas с помощью Pandera
- Введение
- Настраиваемые проверки
- SchemaModel
- Декоратор валидации
- Проверка ввода
- Проверка вывода
- Проверка ввода и вывода
- Другие аргументы проверки столбцов
- Null
- Дубликаты
- Преобразование типов данных
- Сопоставление шаблонов
- Экспорт и загрузка из файла YAML
- Экспорт в YAML
- Загрузка из YAML
- Заключение
- pandas.isnull#
- Python 3: Как узнать версию библиотеки Pandas, Numpy
- Вариант 1. Узнаем версию библиотеки в скрипте Python
- Вариант 2. Проверить с помощью pip менеджера пакетов
- pip list
- pip freeze
- pip show
- Anaconda — conda list
pandas.DataFrame.isna#
Return a boolean same-sized object indicating if the values are NA. NA values, such as None or numpy.NaN , gets mapped to True values. Everything else gets mapped to False values. Characters such as empty strings » or numpy.inf are not considered NA values (unless you set pandas.options.mode.use_inf_as_na = True ).
Mask of bool values for each element in DataFrame that indicates whether an element is an NA value.
Omit axes labels with missing values.
Show which entries in a DataFrame are NA.
>>> df = pd.DataFrame(dict(age=[5, 6, np.NaN], . born=[pd.NaT, pd.Timestamp('1939-05-27'), . pd.Timestamp('1940-04-25')], . name=['Alfred', 'Batman', ''], . toy=[None, 'Batmobile', 'Joker'])) >>> df age born name toy 0 5.0 NaT Alfred None 1 6.0 1939-05-27 Batman Batmobile 2 NaN 1940-04-25 Joker
>>> df.isna() age born name toy 0 False True False True 1 False False False False 2 True False False False
Show which entries in a Series are NA.
>>> ser = pd.Series([5, 6, np.NaN]) >>> ser 0 5.0 1 6.0 2 NaN dtype: float64
>>> ser.isna() 0 False 1 False 2 True dtype: bool
Как проверить данные во фрейме Pandas с помощью Pandera
В науке о данных важно тестировать не только функции, но и данные, чтобы убедиться, что они работают так, как вы ожидали. Материалом о простой библиотеке Pandera для валидации фреймов данных Pandas делимся к старту флагманского курса по Data Science.
Чтобы установить Pandera, в терминале наберите:
Введение
Начнём с простого набора данных, чтобы понять, как работает Pandera:
import pandas as pd fruits = pd.DataFrame( < "name": ["apple", "banana", "apple", "orange"], "store": ["Aldi", "Walmart", "Walmart", "Aldi"], "price": [2, 1, 3, 4], >) fruits
Представьте: ваш менеджер сказал вам, что в наборе данных могут храниться только определённые фрукты, а значение их цены должно быть меньше 4:
available_fruits = ["apple", "banana", "orange"] nearby_stores = ["Aldi", "Walmart"]
Проверка данных вручную может занять много времени, особенно когда их много. Есть ли способ автоматизировать проверку? Да, здесь и пригодится Pandera:
- создадим тесты всего набора данных с помощью DataFrameSchema;
- тесты для каждой колонки — при помощи Column;
- тип теста определим при помощи Check.
import pandera as pa from pandera import Column, Check schema = pa.DataFrameSchema( < "name": Column(str, Check.isin(available_fruits)), "store": Column(str, Check.isin(nearby_stores)), "price": Column(int, Check.less_than(4)), >) schema.validate(fruits)
SchemaError: failed element-wise validator 0: failure cases: index failure_case 0 3 4
- «name»: Column(str, Check.isin(available_fruits)) проверяет, имеет ли столбец name тип string и все ли значения столбца name находятся внутри указанного списка;
- «price»: Column(int, Check.less_than(4)) проверяет, все ли значения в столбце price имеют тип int и меньше 4;
- не все значения в столбце price меньше 4, поэтому тест не проходит.
Другие встроенные методы Checks вы найдёте здесь.
Настраиваемые проверки
Проверки можно писать и через лямбда-выражения. В коде ниже Check(lambda price: sum(price) < 20) проверяет, меньше ли 20 сумма в price.
schema = pa.DataFrameSchema( < "name": Column(str, Check.isin(available_fruits)), "store": Column(str, Check.isin(nearby_stores)), "price": Column( int, [Check.less_than(5), Check(lambda price: sum(price) < 20)] ), >) schema.validate(fruits)
SchemaModel
Когда тесты сложные, чище код сделают не словари, а классы данных. К счастью, Pandera позволяет создавать тесты с классами данных.
from pandera.typing import Series class Schema(pa.SchemaModel): name: Series[str] = pa.Field(isin=available_fruits) store: Series[str] = pa.Field(isin=nearby_stores) price: Series[int] = pa.Field(le=5) @pa.check("price") def price_sum_lt_20(cls, price: Series[int]) -> Series[bool]: return sum(price) < 20 Schema.validate(fruits)
Декоратор валидации
Проверка ввода
Как тестировать входные значения функции? Прямолинейный подход — добавить schema.validate(input) прямо в функцию:
fruits = pd.DataFrame( < "name": ["apple", "banana", "apple", "orange"], "store": ["Aldi", "Walmart", "Walmart", "Aldi"], "price": [2, 1, 3, 4], >) schema = pa.DataFrameSchema( < "name": Column(str, Check.isin(available_fruits)), "store": Column(str, Check.isin(nearby_stores)), "price": Column(int, Check.less_than(5)), >) def get_total_price(fruits: pd.DataFrame, schema: pa.DataFrameSchema): validated = schema.validate(fruits) return validated["price"].sum() get_total_price(fruits, schema)
Но он осложняет тестирование. Функция get_total_price имеет аргументы fruits and schema, а значит, в тест функции нужно включить оба:
def test_get_total_price(): fruits = pd.DataFrame() # Need to include schema in the unit test schema = pa.DataFrameSchema( < "name": Column(str, Check.isin(available_fruits)), "store": Column(str, Check.isin(nearby_stores)), "price": Column(int, Check.less_than(5)), >) assert get_total_price(fruits, schema) == 3
Функция test_get_total_price проверяет и данные, и функцию. Модульный тест должен проверять только одну вещь, поэтому включение проверки данных внутри функции — не идеальное решение.
Эту проблему Pandera решает декоратором check_input. Аргумент декоратора применяется в валидации входных значений:
from pandera import check_input @check_input(schema) def get_total_price(fruits: pd.DataFrame): return fruits.price.sum() get_total_price(fruits)
Если входное значение некорректно, Pandera поднимает исключение до обработки значения в функции:
fruits = pd.DataFrame( < "name": ["apple", "banana", "apple", "orange"], "store": ["Aldi", "Walmart", "Walmart", "Aldi"], "price": ["2", "1", "3", "4"], >) @check_input(schema) def get_total_price(fruits: pd.DataFrame): return fruits.price.sum() get_total_price(fruits)
SchemaError: error in check_input decorator of function 'get_total_price': expected series 'price' to have type int64, got object
Такая проверка до обработки в функции экономит много времени.
Проверка вывода
Для проверки вывода можно использовать декоратор check_output:
from pandera import check_output fruits_nearby = pd.DataFrame( < "name": ["apple", "banana", "apple", "orange"], "store": ["Aldi", "Walmart", "Walmart", "Aldi"], "price": [2, 1, 3, 4], >) fruits_faraway = pd.DataFrame( < "name": ["apple", "banana", "apple", "orange"], "store": ["Whole Foods", "Whole Foods", "Schnucks", "Schnucks"], "price": [3, 2, 4, 5], >) out_schema = pa.DataFrameSchema( ) @check_output(out_schema) def combine_fruits(fruits_nearby: pd.DataFrame, fruits_faraway: pd.DataFrame): fruits = pd.concat([fruits_nearby, fruits_faraway]) return fruits combine_fruits(fruits_nearby, fruits_faraway)
Проверка ввода и вывода
Проверить входные и выходные данные можно с помощью декоратора check_io:
from pandera import check_io in_schema = pa.DataFrameSchema() out_schema = pa.DataFrameSchema( ) @check_io(fruits_nearby=in_schema, fruits_faraway=in_schema, out=out_schema) def combine_fruits(fruits_nearby: pd.DataFrame, fruits_faraway: pd.DataFrame): fruits = pd.concat([fruits_nearby, fruits_faraway]) return fruits combine_fruits(fruits_nearby, fruits_faraway)
Другие аргументы проверки столбцов
Null
По умолчанию Pandera выдаёт ошибку, если в проверяемом столбце есть Null. Если нулевые значения допустимы, в класс Column добавьте nullable=True:
import numpy as np fruits = fruits = pd.DataFrame( < "name": ["apple", "banana", "apple", "orange"], "store": ["Aldi", "Walmart", "Walmart", np.nan], "price": [2, 1, 3, 4], >) schema = pa.DataFrameSchema( < "name": Column(str, Check.isin(available_fruits)), "store": Column(str, Check.isin(nearby_stores), nullable=True), "price": Column(int, Check.less_than(5)), >) schema.validate(fruits)
Дубликаты
По умолчанию дубликаты допустимы. Чтобы они поднимали исключение, добавьте аргумент allow_duplicates=False:
schema = pa.DataFrameSchema( < "name": Column(str, Check.isin(available_fruits)), "store": Column( str, Check.isin(nearby_stores), nullable=True, allow_duplicates=False ), "price": Column(int, Check.less_than(5)), >) schema.validate(fruits)
SchemaError: series 'store' contains duplicate values:
Преобразование типов данных
Аргумент coerce=True изменяет тип данных столбца, если тип не удовлетворяет условию проверки.
В коде ниже тип данных цены изменён с целого на строку:
fruits = pd.DataFrame( < "name": ["apple", "banana", "apple", "orange"], "store": ["Aldi", "Walmart", "Walmart", "Aldi"], "price": [2, 1, 3, 4], >) schema = pa.DataFrameSchema() validated = schema.validate(fruits) validated.dtypes
name object store object price object dtype: object
Сопоставление шаблонов
Что, если мы хотим изменить все столбцы, которые начинаются со слова store?
favorite_stores = ["Aldi", "Walmart", "Whole Foods", "Schnucks"] fruits = pd.DataFrame( < "name": ["apple", "banana", "apple", "orange"], "store_nearby": ["Aldi", "Walmart", "Walmart", "Aldi"], "store_far": ["Whole Foods", "Schnucks", "Whole Foods", "Schnucks"], >)
Pandera позволяет нам применять одни и те же проверки к нескольким столбцам с определённым шаблоном, вот так: regex=True:
schema = pa.DataFrameSchema( < "name": Column(str, Check.isin(available_fruits)), "store_+": Column(str, Check.isin(favorite_stores), regex=True), >) schema.validate(fruits)
Экспорт и загрузка из файла YAML
Экспорт в YAML
YAML — отличный способ показать свои тесты коллегам, не знающим Python. Сохранить все проверки в файле YAML можно с помощью метода schema.to_yaml():
from pathlib import Path # Get a YAML object yaml_schema = schema.to_yaml() # Save to a file f = Path("schema.yml") f.touch() f.write_text(yaml_schema)
Файл schema.yml должен выглядеть примерно так:
schema_type: dataframe version: 0.7.0 columns: name: dtype: str nullable: false checks: isin: - apple - banana - orange allow_duplicates: true coerce: false required: true regex: false store: dtype: str nullable: true checks: isin: - Aldi - Walmart allow_duplicates: false coerce: false required: true regex: false price: dtype: int64 nullable: false checks: less_than: 5 allow_duplicates: true coerce: false required: true regex: false checks: null index: null coerce: false strict: false
Загрузка из YAML
Чтобы загрузить файл, используйте pa.io.from_yaml(yaml_schema):
with f.open() as file: yaml_schema = file.read() schema = pa.io.from_yaml(yaml_schema)
Заключение
Поздравляю! Вы только что узнали, как использовать Pandera для проверки вашего набора данных. Поскольку в науке о данных данные являются важным аспектом проекта, валидация входных и выходных ваших функций позволит сократить количество ошибок на всех этапах работы. Не стесняйтесь форкать исходный код для этой статьи.
А мы поможем вам прокачать навыки или с самого начала освоить профессию, востребованную в любое время:
Краткий каталог курсов и профессий
Data Science и Machine Learning
Python, веб-разработка
Мобильная разработка
От основ — в глубину
pandas.isnull#
This function takes a scalar or array-like object and indicates whether values are missing ( NaN in numeric arrays, None or NaN in object arrays, NaT in datetimelike).
Parameters obj scalar or array-like
Object to check for null or missing values.
Returns bool or array-like of bool
For scalar input, returns a scalar boolean. For array input, returns an array of boolean indicating whether each corresponding element is missing.
Boolean inverse of pandas.isna.
Detect missing values in a Series.
Detect missing values in a DataFrame.
Detect missing values in an Index.
Scalar arguments (including strings) result in a scalar boolean.
ndarrays result in an ndarray of booleans.
>>> array = np.array([[1, np.nan, 3], [4, 5, np.nan]]) >>> array array([[ 1., nan, 3.], [ 4., 5., nan]]) >>> pd.isna(array) array([[False, True, False], [False, False, True]])
For indexes, an ndarray of booleans is returned.
>>> index = pd.DatetimeIndex(["2017-07-05", "2017-07-06", None, . "2017-07-08"]) >>> index DatetimeIndex(['2017-07-05', '2017-07-06', 'NaT', '2017-07-08'], dtype='datetime64[ns]', freq=None) >>> pd.isna(index) array([False, False, True, False])
For Series and DataFrame, the same type is returned, containing booleans.
>>> df = pd.DataFrame([['ant', 'bee', 'cat'], ['dog', None, 'fly']]) >>> df 0 1 2 0 ant bee cat 1 dog None fly >>> pd.isna(df) 0 1 2 0 False False False 1 False True False
>>> pd.isna(df[1]) 0 False 1 True Name: 1, dtype: bool
Python 3: Как узнать версию библиотеки Pandas, Numpy
Вариант 1. Узнаем версию библиотеки в скрипте Python
Для того, чтобы узнать версию библиотеки, необходимо вбить следующую команду (например для Pandas):
import pandas as pd print (pd.__version__)
Пример для Numpy:
import numpy as np print (np.__version__)
Вариант 2. Проверить с помощью pip менеджера пакетов
С помощью менеджера пакетов pip можно проверить версию установленных библиотек, для этого используются команды:
pip list
Выведет список установленных пакетов, включая редактируемые.
pip freeze
Выводит установленные пакеты, которые ВЫ установили с помощью команды pip (или pipenv при ее использовании) в формате требований.
Вы можете запустить: pip freeze > requirements.txt на одной машине, а затем на другой машине (в чистой среде) произвести инсталляцию пакетов: pip install -r requirements.txt .
Таким образом вы получите идентичную среду с точно такими же установленными зависимостями, как и в исходной среде, в которой вы сгенерировал файл requirements.txt.
pip show
Выводит информацию об одном или нескольких установленных пакетах.
Anaconda — conda list
Если вы используете Anaconda, то вы можете проверить список установленных пакетов в активной среде с помощью команды conda list .