簡體   English   中英

Pandas 按日期和 id 計數/添加值

[英]Pandas counting/adding values by date and id

我想計算在每個訂單日期之前已付款的所有訂單。

輸入:
在此處輸入圖像描述

預期 output:
在此處輸入圖像描述

以下代碼有效,但速度極慢。 100k+ 行需要超過 10 個小時。 當然有更好的方法。

orders_paid,orders_inkasso = []

for y,row in df_dated_filt.iterrows():
    x = x + 1
    orders_paid.append(df_dated_filt[(df_dated_filt["order_id"] != row["order_id"]) & (df_dated_filt["m_order_paid"] == 1) & 
                      (df_dated_filt["customer_id"] == row["customer_id"]) & 
                      (pd.to_datetime(df_dated_filt['order_date'])<pd.to_datetime(row['order_date']))]["order_id"].count())
df_dated_filt["m_orders_paid"] = orders_paid

使用sort_values以升序獲取日期,然后使用cumsum + shift進行groupby transform以獲取基於當前日期之前的總支付:

df['order_date'] = pd.to_datetime(df['order_date'])

df['total_paid'] = (
    df.sort_values('order_date')
        .groupby('customer_id')['order_paid']
        .transform(lambda g: g.cumsum().shift(fill_value=0))
)

df

   customer_id  order_id order_date  order_paid  total_paid
0            1        12 2019-01-06           0           1
1            1        22 2019-01-01           1           0
2            1        31 2019-01-03           0           1
3            2        34 2018-05-08           0           0
4            2        44 2018-05-12           1           0
5            2        48 2018-05-29           1           1
6            2        55 2018-05-30           1           2

(注意我認為第一行應該是 1,因為該客戶在 2019 年 1 月 1 日有一個已付款訂單,第一行是 2019 年 1 月 1 日之后的 2019 年 1 月 6 日。此外,提供的代碼也放第一行中的 1。)


完整的工作示例:

import pandas as pd

df = pd.DataFrame({
    'customer_id': [1, 1, 1, 2, 2, 2, 2],
    'order_id': [12, 22, 31, 34, 44, 48, 55],
    'order_date': ['2019-01-06', '2019-01-01', '2019-01-03',
                   '2018-05-08', '2018-05-12', '2018-05-29', '2018-05-30'],
    'order_paid': [0, 1, 0, 0, 1, 1, 1]
})
df['order_date'] = pd.to_datetime(df['order_date'])

df['total_paid'] = (
    df.sort_values('order_date')
        .groupby('customer_id')['order_paid']
        .transform(lambda g: g.cumsum().shift(fill_value=0))
)
print(df)

假設更多操作依賴於按升序排列的日期,則按customer_idorder_date對 DataFrame 進行排序可能是有益的:

df = df.sort_values(['customer_id', 'order_date'])

那么以后的操作就不需要排序了:

df['total_paid'] = (
    df.groupby('customer_id')['order_paid']
        .transform(lambda g: g.cumsum().shift(fill_value=0))
)

然后在所有訂購的日期相關操作完成后使用:

df = df.sort_values(['customer_id', 'order_id'])

恢復幀的原始順序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM