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似乎是错误的。我使用了所提供的工作代码片段的输出,这是我根据其得出的答案。也就是说,我进行了编辑,在最后添加了有关排序的信息。=)