Напишите необязательную исполняемую (ленивую) функцию для столбцов Pandas

#pandas #dataframe

Вопрос:

Я пытаюсь написать сценарий с необязательными «вызываемыми» столбцами.

Основная суть :

У нас есть базовый фрейм данных примерно с 25 столбцами. Средняя длина ~ 3000 строк. Существует множество дополнительных атрибутов, которые могут быть добавлены при вызове — возможно до 80 дополнительных вычислений.

Однако только в том случае, если некоторые вычисления будут успешными с несколькими ответвлениями (которые будут выбраны пользователем), мы приступаем к последующим дополнениям.

Вопрос: Я хотел бы определить все эти дополнительные столбцы здесь как функции для ленивого выполнения, т. Е. выполняемые только по требованию, вместо предварительного вычисления всех этих 80 столбцов и добавления в фрейм данных.

Для пользователя это все равно дало бы один результат.

Будут ли полезны функции лямбды?

 df = df.assign(IsDate = lambda x:(x.dt lt; date(2021,11,1)))  

Где столбец [«Дата»] должен быть выполнен лениво. Но, приведенное ниже (эквивалентно ли это) не поленилось бы.

 df['IsDate'] = x.dt lt; date(2021,11,1)  

Я не уверен, что мой вопрос ясен.

Ответ №1:

Вопрос: Я хотел бы определить все эти дополнительные столбцы здесь как функции для ленивого выполнения, т. Е. выполняемые только по требованию, вместо предварительного вычисления всех этих 80 столбцов и добавления в фрейм данных.

Почему бы вам просто не создать функции, которые добавляют нужные столбцы в фрейм данных, передаваемый в качестве аргумента? И вы вызываете эти функции только тогда, когда выполняется заданное условие.

 df = df.assign(IsDate = lambda x:(x.dt lt; date(2021,11,1)))  df['IsDate'] = x.dt lt; date(2021,11,1)  

Эти две строки эквивалентны. Первый выполняется не лениво, столбец создается сразу после выполнения строки.

Разве ты не хочешь чего-то вроде

 # if condition 1 is satisfied compute and add the 'IsDate' column to df if cond_1:   df['IsDate'] = x.dt lt; date(2021,11,1)  # if also condition 2 is satisfied, add 'new_column1'  if cond_2:  df['new_column1'] = ....    if cond_3:  df['new_column2'] = ....   

Конечно, вы не должны вкладывать слишком много утверждений if. Я уверен, что есть лучшие способы справиться с управлением потоком в зависимости от того, что именно вы хотите, что я не до конца понял.

Для более сложных вычислений вы можете поместить логику внутри функций

 def add_isdate(df):  """ function that adds 'Isdate' to df. Mutates df in-place."""    df['IsDate'] = x.dt lt; date(2021,11,1)  def add_related_cols(df):  """ function that computes several similar calculations   and add them as columns to df. Mutates df in-place."""   df['col1'] = (...)  # do other computations   df['col2'] = (...)  # (...)  df = pd.DataFrame(...)  # Add 'IsDate' to df (in-place) if cond_1 is met  if cond_1:  add_isdate(df)  # if cond_2 is met, do a bunch of computations and add them to df (in-place) if cond_2:  add_related_cols(df)  

Если вы не хотите, чтобы функции добавляли столбцы на месте, вы можете создать копию переданного фрейма данных и вернуть другой фрейм данных с дополнительными столбцами

 def add_column_not_inplace(df):  """ computes new column(s). Returns a new   DataFrame with the additional column(s) """  # make a copy of the DataFrame passed  df_copy = df.copy()    # compute and add the new columns  df_copy['new_col'] = (...)  # (...)    # returns the copy of the original df with the new columns   return df_copy   df = pd.DataFrame(...)  # if cond_1 is met, add the column to df.  # Assign the result to df1 as the functions doesn't act in-place if cond_1:  df1 = add_column_not_inplace(df)  

Комментарии:

1. @Kapil Это ответ на ваш вопрос? Если нет, пожалуйста, уточните, чего вы хотите.