簡體   English   中英

熊貓:條件累積和的矢量化

[英]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.

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