Быстрее l oop in Pandas ищет идентификатор и более старую дату - PullRequest
0 голосов
/ 12 апреля 2020

Итак, у меня есть DataFrame, который представляет покупки с 4 столбцами:

  1. дата (дата покупки в формате% Y-% m-% d)
  2. customer_ID (строка столбец)
  3. претензия (1-0 столбец означает, что 1 - покупатель жаловался на покупку, 0 - покупатель не жаловался)
  4. претензия_значение (для претензии = 1 это означает, сколько стоимость претензии компании, для претензии = 0 это NaN)

Мне нужно построить 3 новых столбца:

  1. past_purchases (сколько покупок указывает конкретный c клиент до этой покупки)
  2. past_claims (сколько претензий было у указанного клиента c до этой покупки)
  3. past_claims_value (сколько стоили прошлые претензии клиента)

Это мой подход до сих пор:

past_purchases = []
past_claims = []
past_claims_value = []

for i in range(0, len(df)):
    date = df['date'][i]
    customer_ID = df['customer_ID'][i]
    df_temp = df[(df['date'] < date) & (df['customer_ID'] == customer_ID)]
    past_purchases.append(len(df_temp))
    past_claims.append(df_temp['claim'].sum())
    past_claims_value.append(df['claim_value'].sum())

df['past_purchases'] = pd.DataFrame(past_purchases)
df['past_claims'] = pd.DataFrame(past_claims)
df['past_claims_value'] = pd.DataFrame(past_claims_value)

Код работает нормально, но он слишком медленный. Кто-нибудь может заставить его работать быстрее? Спасибо!

Ps: Важно проверить, что дата старше, если у клиента было 2 покупки в одну и ту же дату, они не должны учитываться друг для друга.

Pss: Я готов использовать библиотеки для параллельной обработки, такие как многопроцессорная обработка, concurrent.futures, joblib или dask, но никогда раньше не было подобным образом.

Ожидаемый результат:

enter image description here

1 Ответ

0 голосов
/ 12 апреля 2020

Может быть, вы можете попробовать использовать cumsum для клиентов, если даты отсортированы по возрастанию

df.sort_values('date', inplace=True)

new_temp_columns = ['claim_s','claim_value_s']
df[['claim_s','claim_value_s']] = df[new_temp_columns].shift()
df['past_claims'] = df.groupby('customer_ID')['claim_s'].transform(pd.Series.cumsum)
df['past_claims_value'] = df.groupby('customer_ID')['claim_value_s'].transform(pd.Series.cumsum)

# set the min value for the groups
dfc = data.groupby(['customer_ID','date'])[['past_claims','past_claims_value']]
data[['past_claims', 'past_claims_value']] = dfc.transform(min)

# Remove temp columns     
data = data.loc[:, ~data.columns.isin(new_temp_columns)]

Опять же, это будет работать, только если даты являются srotes

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...