首页 > 解决方案 > Featuretools:使用 Pandas 'rolling' 生成滚动总和、平均值等,但以天为单位进行偏移

问题描述

我正在尝试在 Featuretools 中创建一个自定义 TransformPrimitive 来计算滚动统计信息,例如滚动总和或平均值。

本文很好地解释了如何使用 Pandas 完成此类任务。它显示了在使用“窗口”参数表示用于计算统计数据的观察数时如何让事情运行。

但是,我打算提供一个字符串输入来计算以天为单位的偏移量。下面的行从概念上正确计算了我需要的东西。

transactions.groupby('ID').rolling(window='10D', on='TransactionDate')[['Quantity','AmountPaid']].sum()

TransformPrimitive 如下所示:

class RollingSum(TransformPrimitive):
    """Calculates the rolling sum.

    Description:
        Given a list of values, return the rolling sum.
    """

    name = "rolling_sum"
    input_types = [NaturalLanguage,NaturalLanguage]
    return_type = Numeric
    uses_full_entity = True
    description_template = "the rolling sum of {}"

    def __init__(self, window=None, on=None):
        self.window = window
        self.on = on

    def get_function(self):
        def rolling_sum(values):
            """method is passed a pandas series"""
            return values.rolling(window=self.window, on=self.on).sum()

        return rolling_sum

我试图从实体集中传递 TransactionDate 变量:

features_defs = ft.dfs(
    entityset=es,
    max_depth=2,
    target_entity='CUSTOMER',
    agg_primitives=['sum'], 
    groupby_trans_primitives=[
      RollingSum(window='10D', on=es['TRANSACTION']['TransactionDate'])
    ], 
    cutoff_time = label_times,
    cutoff_time_in_index=False,
    include_cutoff_time=False,
    features_only=True
)

但没有成功。我收到未使用的原始警告:

在 DFS 期间未使用某些指定的原语: groupby_trans_primitives: ['rolling_sum'] 这可能是由于使用的 max_depth 值太小,未设置有趣的值,或者可能表明未找到原语的兼容变量类型在数据中。警告.warn(warning_msg, UnusedPrimitiveWarning)

非常感谢您的建议!

标签: pythonpandasfeaturetools

解决方案


您尝试将 Datetime 变量 , 提供es['TRANSACTION']['TransactionDate']给 on 参数是正确的,但 Pandas 不知道如何处理 Featuretools 变量,因此这可能是创建新 Primitive 的好机会RollingSumOnDatetime

您可以在RollingSum此处对原语进行一些更改,以便它可以使用您的日期时间列。

  1. input_types应该是[Numeric, DatetimeTimeIndex]因为用于滚动平均值的日期时间列必须存在于用于进行pd.DataFrame.rolling 调用的数据中。Numeric 变量是因为滚动只能在数字列上计算。该DatetimeTimeIndex变量确保该系列将是单调的日期时间(因为 featuretools 将对时间索引进行排序),这是计算滚动总和的另一个要求。
  2. rolling_sum 函数应该将NumericDatetimeTimeIndex列组合成一个 DataFrame 并且滚动应该根据所需窗口计算。

我在想象 Primitive 看起来像这样:

class RollingSumOnDatetime(TransformPrimitive):
    """Calculates the rolling sum on a Datetime time index column.
    Description:
        Given a list of values and a Datetime time index, return the rolling sum.
    """
    name = "rolling_sum_on_datetime"
    input_types = [Numeric, DatetimeTimeIndex]
    return_type = Numeric
    uses_full_entity = True
    description_template = "the rolling sum of {} on {}"
    def __init__(self, window=None):
        self.window = window
    def get_function(self):
        def rolling_sum(to_roll, on_column):
            """method is passed a pandas series"""
            #create a DataFrame that has the both columns in it
            df = pd.DataFrame({to_roll.name:to_roll, on_column.name:on_column})
            rolled_df = df.rolling(window=self.window, on=on_column.name).sum()
            return rolled_df[to_roll.name]
        return rolling_sum

推荐阅读