[英]Pandas: vectorization of Conditional Cumulative Sum
我正在尝试在熊猫中向量化for循环以提高性能。 我有一个数据集,包括用户,产品,每个服务的日期以及提供的天数。 给定以下数据子集:
testdf = pd.DataFrame(data={"USERID": ["A"] * 6,
"PRODUCTID": [1] * 6,
"SERVICEDATE": [datetime(2016, 1, 1), datetime(
2016, 2, 5),
datetime(2016, 2, 28), datetime(2016, 3, 25),
datetime(2016, 4, 30), datetime(2016, 5, 30)],
"DAYSSUPPLY": [30] * 6})
testdf=testdf.set_index(["USERID", "PRODUCTID"])
testdf["datediff"] = testdf["SERVICEDATE"].diff()
testdf.loc[testdf["datediff"].notnull(), "datediff"] = testdf.loc[
testdf["datediff"].notnull(), "datediff"].apply(lambda x: x.days)
testdf["datediff"] = testdf["datediff"].fillna(0)
testdf["datediff"] = pd.to_numeric(testdf["datediff"])
testdf["over_under"] = testdf["DAYSSUPPLY"].shift() - testdf["datediff"]
我想得到以下结果:
DAYSSUPPLY SERVICEDATE datediff over_under desired
USERID PRODUCTID
A 1 30 2016-01-01 0 NaN 0
1 30 2016-02-05 35 -5.0 0
1 30 2016-02-28 23 7.0 7
1 30 2016-03-25 26 4.0 11
1 30 2016-04-30 36 -6.0 5
1 30 2016-05-30 30 0.0 5
本质上,我希望我的期望列为over_under的运行总和,但仅在前一行的期望值> 0时才求和负值。期望值永远不应低于0。[用户,产品]组看起来像这样:
running_total = 0
desired_loop = []
for row in testdf.itertuples():
over_under=row[4]
# skip first row
if pd.isnull(over_under):
desired_loop.append(0)
continue
running_total += over_under
running_total = max(running_total, 0)
desired_loop.append(running_total)
testdf["desired_loop"] = desired_loop
desired_loop
USERID PRODUCTID
A 1 0.0
1 0.0
1 7.0
1 11.0
1 5.0
1 5.0
我对矢量化,熊猫和一般游戏还不陌生。 我已经能够矢量化此df中的所有其他计算,但是这种累计和的特殊情况我只是不知道如何进行。
谢谢!
我有一个类似的问题,并使用了一些非常规的迭代来解决了。
testdf["desired"] = testdf["over_under"].cumsum()
current = np.argmax( testdf["desired"] < 0 )
while current != 0:
testdf.loc[current:,"desired"] += testdf["desired"][current] # adjust the cumsum going forward
# the previous statement also implicitly sets
# testdf.loc[current, "desired"] = 0
current = np.argmax( testdf["desired"][current:] < 0 )
本质上,您会发现所有“事件”并随着时间重新调整运行的累计量。 所有的操作和测试操作都是矢量化的,因此,如果desired
列不会太频繁地与负数交叉,那么您应该非常快。
这绝对是一个hack,但它为我完成了工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.