パフォーマンスを向上させるために、パンダの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の実行中の合計になりたいが、唯一の合計に私は
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
:前のライン上の所望の値が0を下回る[ユーザー、製品]グループの上に迅速かつ汚いループを取得することはありません希望> 0の場合、負の値が次のようになりますセントベクタライゼーションやパンダ、そして一般的に新しいものではありません。私はこのdfで他のすべての計算をベクトル化することができましたが、この特殊な累積合計のケースでは、どうやってそれを調べるのか分かりません。
ありがとうございます!