Многие Data Scientist’ы используют библиотеку Pandas, но даже не подозревают о существовании наследования классов. В этой статье мы расскажем вам, как наследование от DataFrame делает ваш код более читаемый и воспроизводимым.
В чем заключается проблема DataFrame из Pandas
Аналитики и инженеры данных обычно представляют данные в виде объекта DataFrame, который используется во всем коде. Поэтому многие операции связаны с этим объектом: его передают в функции, возвращают, преобразовывают, удаляют и т.д. Например, ниже функция на Python, которая принимает на вход DataFrame и возвращает столбец со средними значениями.
def calculate_mean(students_df): # ... остальной код return df['scores'].mean()
Как можно заметить, название столбца мы определяли в виде строки (string). Иными словами, используются строковые значения средства взаимодействия. Иными словами, требуется знать и помнить о деталях реализации. А если датафреймов больше одного, то нужно помнить у кого какие столбцы. При повторном обращении к коду придется снова вспоминать где что. Поэтому если мы думаем о сопровождении кода в будущем, то лучше так не делать.
С другой стороны, мы можем завести класс, который будет иметь поля с названиями столбцов. Пример такого класс на Python продемонстрирован ниже.
class StudentsData: SCORES = 'scores' STUDENT_NAME = 'student_name'
Так, теперь функцию для подсчета среднего значения переписывается следующим образом:
from student_data_def import StudentsData def calculate_mean(students_df): # ... return df[StudentsData.SCORES].mean()
Такой код выглядит немного лучше. Но появилась новая проблема: класс StudentsData
и датафрейм students_df
не связаны. Мы можем по имени класса догадаться, что он относится к конкретному датафрейму и ничему больше. Но догадки, связанные с кодом, лучше оставить в стороне. Другая проблема заключается в том, что нужно постоянно импортировать его там, где используется датафрейм. Такой модуль придется перезагружать при внесении изменений, если вы используете Jupyter Notebook.
Если вы используете Python 3.5 и выше, то возможно вам пригодятся подсказки типов (type hints), которые в связке с различными линтерами (о которых мы говорили тут) помогают выявлять несоответствия типов. Аннотируем подсказками нашу функцию:
def calculate_mean(students_df: pd.DataFrame) -> np.float: # ... return df[StudentsData.SCORES].mean()
Аннотация pd.DataFramе
не дает больше информации, чем имя переменной. Как понять, какие столбцы доступны? И опять придется помнить именно об этом объекте во всем коде.
Подготовка данных для Data Mining на Python
Код курса
DPREP
Ближайшая дата курса
по запросу
Продолжительность
32 ак.часов
Стоимость обучения
72 000 руб.
Итак, проблемы были обозначены, хотелось бы всё-таки создать единый класс, который бы объединял и класс с полями, и датафрейм. Такой класс должен удовлетворять следующим условиям:
- не должно быть ни какого строкового обращения к столбцам,
- класс и поля должны быть связаны,
- должна быть возможность использовать его c подсказками типов.
Решение — наследование классов Pandas
Наследование от pd.DataFrame
решает перечисленные проблемы. Для этого вам нужно определить метод _constructor
и вернуть нужный класс. Пример того, как можно переписать код выше:
import pandas as pd class StudentsDF(pd.DataFrame): SCORES = 'scores' STUDENT_NAME = 'name' @property def _constructor(self): return StudentsDF x = StudentsDF(data=dict(name=['Alice', 'Bob'], scores=[60, 50])) type(x) # __main__.StudentData
Этот же класс можно использовать в качестве аннотации типов:
def calculate_mean(df: StudentsDF): # ... return df[df.SCORES].mean()
Обратите внимание, что с помощью этой конструкции также можно создать экземпляр типа StudentDF
из файла (точнее по указанию пути до него):
df = pd.read_csv('/tmp/t.csv') students_df = StudentsDF(df) print(student_df.columns)
Вот таким нехитрым способом можно сделать свой код более приятным для сопровождения при использовании библиотеки Pandas.
А о том, как проводить анализ данных с помощью библиотеки Pandas на реальных примерах Data Science вы узнаете на специализированных курсах в лицензированном учебном центре обучения и повышения квалификации разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве.
- FUNP: Основы языка Python для анализа данных и решения задач машинного обучения
- DPREP: Подготовка данных для Data Mining на Python
- PYML: Машинное обучение на Python