下面的数据集指示每个客户哪些产品处于活动状态以及什么月份。
一个月可以取几个值(1、2、3等),有许多乘积(x,y,z等),而product_active是二进制值以指示活动状态。

cust_id month product  product_active
1234    1     x        1
1234    2     x        0
1234    1     y        0
1234    2     y        1


从第1个月到第2个月,我该如何选择从产品x切换到产品y的所有客户?我想对此进行概括,即能够选择从m1个月到m2个月从产品a切换到产品b的所有客户。

最佳答案

好的,也许有一种使用.groupby()和矢量解决方案的更蟒蛇的方法,但是这里有一个解决方案,它将为df提供您想要的结果。我根据您的数据做出的假设是您的产品有效期列无关紧要。

#DF Setup
_______________________
col = ['cust_id', 'month', 'product',  'product_active']
data = [
(1234,    1,     'x',        1 ),
(1234,    2,     'x',        0 ),
(1235,    1,     'y',        0 ),
(1235,    2,     'y',        1 ),
(1236,    1,     'x',        1 ),
(1236,    2,     'y',        0 )]
df = pd.DataFrame(data, columns=col)


添加了一个额外的客户(1236)以模拟产品从m1到m2的变化(x-> y)。

#Solution
______________________
result_df = pd.DataFrame()

for i,row in df.iterrows():
    if i == 0:
        pass
    elif df.loc[i-1,'cust_id'] == df.loc[i,'cust_id']:
        if (df.loc[i-1,'month'] == 1) & (df.loc[i,'month'] == 2):
            if (df.loc[i-1,'product'] == 'x') & (df.loc[i,'product'] == 'y'):
                result_df = result_df.append(df.loc[i])


这是包装在函数中的通用解决方案:

def filter_function(month,p1,p2):
    '''
    month - month you wish to check for product change.
    p1 - "From" product
    p2 - "To" product
    '''
    result_df = pd.DataFrame()

    for i,row in df.iterrows():
        if i == 0:
            pass
        elif df.loc[i-1,'cust_id'] == df.loc[i,'cust_id']:
            if (df.loc[i-1,'month'] == month-1) & (df.loc[i,'month'] == month):
                if (df.loc[i-1,'product'] == p1) & (df.loc[i,'product'] == p2):
                    result_df = result_df.append(df.loc[i])
    return result_df

filter_function(2,'x','y')

09-26 18:59
查看更多