Comments 12
стиль записи кода, который позволяет выполнять несколько операций за один раз, в конечном счете экономя время и энергию
Это неверное утверждение: операции выполняются последовательно. Ни время, ни энергия не экономятся. Цепочка методов экономит время программиста, упрощая чтение кода.
Запись методов в одну строчку в таких цепочках (как в вашем первом примере с котом, и далее несколько раз в тексте) усложняет отладку.
Важно понимать потенциальные недостатки и проблемам, прежде чем переходить к этому подходу: … может быть неэффективным в вычислительном отношении. Если для анализа требуется много операций, стоимость их выполнения в рамках одной операции может быть довольно высокой.
Можете пример привести?
Не ну моё же время и энергия экономится, чем не экономия)
По поводу второго, были случаи, что у меня система крашилась на фреймах больше 300кк строчек, но в связке при перехвате на переменную + with multiprocessing.Pool() as pool позволяло обойти ограничения. Возможно связано с внутренним устройством самих панд. Если не найду примеры, то подправлю текст. Но это будет еще один плюс в использование этого метода)
Упрощает отладку? Скорее наоборот. Я не могу поставить промежуточные print, чтобы посмотреть на данные, могу только увидеть конечный фрейм. И кто его знает, что где пошло не так в этой цепочке.
считается, что цепочка методов более эффективна, чем отдельные шаги, поскольку операции могут выполняться последовательно без создания промежуточных фреймов, которые увеличивают использование памяти pandas.
Кем считается? Фреймов будет создано ровно столько же, сколько и при одиночных операциях - это определяется самими функциями, в не способом их вызова.
Я не могу поставить промежуточные print
Сэр вы все можете, но зачем?!:
from IPython.display import display
d = {'col1': [1,2,3,4,5,6],'col2': [7,8,9,10,11,12],'col3': ['a','b','a','b','a','g'] }
df = pd.DataFrame(data = d)
(
df
.pipe(lambda _df:print(_df) or _df)
.assign(col_4=lambda _df:_df['col2'])
# ну или display например
.pipe(lambda _df:display(_df) or _df)
.assign(col_5=lambda _df:_df['col_4']*5)
)
Использование or _df в lambda позволяет пробросить фрейм дальше и продолжить цепочку!
Кем считается?
mr. Marc Garcia основная команда pandas https://www.youtube.com/watch?v=hK6o_TDXXN8, 6:52 цитата "Я думаю так должны выглядеть панды в будущем".
надеюсь панда умрёт от старости в скором будущем освободив поляну для polars/arrow/DuckDB
Пандас вечен! Как и ексель) Реально, это уже стандарт, стандарт просто так уже не умрет. Скорее остальные команды будут копировать API пандас, и выделять это как преимущество. Например так уже поступает modine.
Реально, это уже стандарт, стандарт просто так уже не умрет.
Если что, статья от Веса Маккини, создателя пандас
Apache Arrow and the "10 Things I Hate About pandas"
а здесь можно полюбоваться на горячо_любимый_пандас в бенчмарках от h2o
Ну хорошо, хоть про количество промежуточных фреймов не спорите ?
Хаха), вот тут например утверждается, что обычное сложение:
df['D'] = df['A'] + df['B']
df['E'] = df['A'] * df['C']
Из-за внутренней работы pandas это приведет к копированию всего фрейма данных в новое место в памяти (для подробного объяснения ознакомьтесь выступлением Марка Гарсии, члена основной команды pandas), тогда как упаковка его в один .assign() помогает достичь этого в один шаг. Это имеет большое значение для больших наборов данных и нескольких новых столбцов.
Статья понравилась, но кода местами чуть многовато. Цепные вызовы можно дергать без скобок и pipe, просто через точку: df.loc[...].query(...).assign(...) или ...eval(...) позволяют в одну строку, "налету", вычислить новый столбец и добавить его справа в df.
Но pipe и скобки из статьи позволяют в Jupyter/Lab/IDE нажатием на Ctrl+/ выборочно "комментировать" строки из "цепи", что удобно при отладке или аналитических итерациях (а весь анализ всегда и у всех именно такой, мелкими шажками, иногда откровенно тупыми). Хорошо что в Pandas можно комбинировать "длинный" и "широкий" код не под PEP8, а под собственные итерации, которые у каждого аналитика и на каждых новых данных - свои.
Кроме того, цепные методы проще в наборе. "Дописать" легче чем "обернуть" или залямбдить, сравните:
df.цена # даст столбец цен вида 12345.678901
df.цена.коп() # даст столбец цен вида 12345.68
Чтобы это сработало, нужно заранее объявить новый метод Series:
коп = lambda n: round(n, 2)
pd.Series.коп = коп
Любые другие способы округления (df.цена.round(2) итд) - будут более многословны в наборе и потребуют переключения языка ввода. Таблицы с русскими колонками понятны всем, "русские методы" легко запоминаются аналитиками, визуально custom-методы df/Series отличимы от сотен встроенных и работают в Python/Pandas безупречно. Для порядка можно в UDF-лямбду добавить Docstrings:
коп.doc = 'Округляет в копейки. Можно df.коп(), df.col.коп(), df.apply(коп), df.col.apply(коп)'
Цепочка методов в pandas. Прокачиваем свой код. Минигайд для интересующихся