Python 按日期和id计算/添加值

Python 按日期和id计算/添加值,python,pandas,numpy,Python,Pandas,Numpy,我想数一数在每次订单日期之前已经付款的所有订单 输入: 预期输出: 下面的代码可以工作,但速度非常慢。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[&q

我想数一数在每次订单日期之前已经付款的所有订单

输入:

预期输出:

下面的代码可以工作,但速度非常慢。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
orders\u paid,orders\u inkasso=[]
对于y,df_dated_filt.iterrows()中的行:
x=x+1
订单已付。追加(df_Date_filt[(df_Date_filt[“订单id”!=行[“订单id”])和(df_Date_filt[“m_订单已付”]=1)和
(df_dated_filt[“customer_id”]==行[“customer_id”])和
(pd.to_datetime(df_dated_filt['order_date'])用于按升序获取日期,然后使用+获取当前日期之前的总付款:

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-01-01有一个已付款订单,第一行在2019-01-06,即2019-01-01之后。此外,提供的代码也将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)

假设更多的操作取决于日期的升序,则按
客户id
订单日期对数据框进行排序可能会有好处:

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'])

恢复帧的原始顺序。

df.groupby('Team')['Count'].transform(lambda x:x.cumsum().shift().fillna(0))
?如果改为
打印(df.sort_值(['customer_id','order_date'))
结果会更容易阅读。我同意。但是,OP的预期输出保持了数据帧的原始顺序,这就是我采用这种方法的原因。也就是说,排序肯定是个好主意,特别是如果要执行依赖于按排序顺序排列的日期的其他操作。啊,我没有注意到因此,发布的示例OP似乎是错误的。我使用了所提供的工作代码片段的输出,这是我根据其得出的答案。也就是说,我进行了编辑,在最后添加了有关排序的信息。=)