Сложный выбор в панде - PullRequest
       2

Сложный выбор в панде

2 голосов
/ 23 сентября 2019

Приведенный ниже набор данных указывает, какие продукты активны для каждого клиента и в каком месяце.Месяц может принимать несколько значений (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   

Как выбрать всех клиентов, которые перешли с продукта x на продукт y с 1 по 2 месяц?Я хотел бы обобщить это, т.е. иметь возможность выбирать всех клиентов, которые перешли с продукта a на продукт b, с месяца m1 на месяц m2.

Ответы [ 2 ]

1 голос
/ 23 сентября 2019

Проверьте, работает ли это для вас

mask = df['product_active'].ne(df['product_active'].shift(2))
a = df[~mask & df.product_active==1]['cust_id']
Cust_not_switching = list(set(df[df['cust_id'].isin(a)]['cust_id'].to_list()))
Cust_switching = list(set(df[~df['cust_id'].isin(a)]['cust_id'].to_list()))

Вход

cust_id     month   product     product_active
0   1234    1   x   1
1   1234    2   x   0
2   1234    1   y   0
3   1234    2   y   1
4   1235    1   x   1
5   1235    2   x   1
6   1235    1   y   0
7   1235    2   y   0
8   1236    1   x   0
9   1236    2   x   1
10  1236    1   y   1
11  1236    2   y   0

Выход

Cust_not_switching = [1235]
Cust_switching = [1234, 1236]

Это будет работать, только если есть 2 продукта.

1 голос
/ 23 сентября 2019

Хорошо, может быть более питонский способ сделать это, используя .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) для имитации изменения продукта (x-> y) с m1 на m2.

#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')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...