Изменение отрицательных значений на 0 без изменения других столбцов - PullRequest
2 голосов
/ 14 января 2020

У меня есть DF, в котором я анализирую общую стоимость клиента. Я нахожу общую цену, уплаченную клиентом путем суммирования скидки (поскольку это уже отрицательное число) от продажной стоимости продукта.

transaction_df_clean['customer_price'] = transaction_df_clean['sales_value'] + transaction_df_clean['coupon_disc']

Следовательно, некоторые итоговые цены являются отрицательными, и я хочу изменить их на 0, чтобы избежать отрицательных чисел.

Ввод:

transaction_df_clean.loc[transaction_df_clean['customer_price'] < 0].head(10)

Вывод (отображается 1 строка):

index   household_key   basket_id   day product_id  quantity    sales_value store_id    retail_disc trans_time  week_no coupon_disc coupon_match_disc   customer_price
----------
13895   988  27282152470     25  1088634    2   1.00    408 -0.98   2353    4   -1.49   0.00    -0.49

Однако при попытке изменить отрицательные значения на 0 в столбцах «customer_price» изменяются другие столбцы, которые не являются целевыми. на 0 тоже.

Ввод:

transaction_df_clean.loc[transaction_df_clean['customer_price'] < 0] = 0
transaction_df_clean.loc[transaction_df_clean['customer_price'] == 0].head(20)

Ввод:

index household_key basket_id   day product_id  quantity    sales_value store_id    retail_disc trans_time  week_no coupon_disc coupon_match_disc   customer_price
----------
13895   0   0   0   0   0   0.00    0   0.00    0   0   0.00    0.00    0.0

Есть идеи, почему это может происходить?

Ответы [ 3 ]

2 голосов
/ 14 января 2020

Вам также нужно выбрать столбец.

m = transaction_df_clean['customer_price'] < 0
transaction_df_clean.loc[m,'customer_price']=0

Я бы использовал Series.clip.

transaction_df_clean['customer_price'] = transaction_df_clean['customer_price'].clip(lower=0)

Мы также могли бы использовать Series.mask.

transaction_df_clean['customer_price']=transaction_df_clean['customer_price'].mask(m,0)

Так что вам нужно Series.add + Series.clip:

transaction_df_clean['customer_price'] = transaction_df_clean['sales_value'].add(transaction_df_clean['coupon_disc']).clip(lower=0)
1 голос
/ 14 января 2020

Что на самом деле делает transaction_df_clean.loc[transaction_df_clean['customer_price'] < 0] = 0, так это применяет условие ко всему фрейму данных, и когда вы добавляете = 0, 0 транслируется во все точки данных. Вы предлагаете выбрать все строки в вашем фрейме данных, где customer_price меньше 0, а затем изменить все отфильтрованные строки на 0.

Помимо применения условия, вы должны выбрать нужный столбец / серию изменить.

Как я помню, использовать .loc это df.loc[row filter/selection, column filter/selection]

Другой способ сделать это будет

transaction_df_clean.loc[transaction_df_clean['customer_price'] < 0,'customer_price'] = 0

Там является хорошим разделом в документации о настройках значений, называемых Уставки https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.loc.html

0 голосов
/ 14 января 2020

вы можете использовать numpy.max для его обработки (pandas также имеет max, но он менее интуитивно понятен, поскольку по умолчанию агрегирует данные, а не работает для каждой строки)

import numpy as np 

transaction_df_clean['customer_price'] = np.max(0, transaction_df_clean['sales_value'] + transaction_df_clean['coupon_disc'])

this как не будет никаких отрицательных чисел

...