我的 DF 目前只有前兩列 DATE 和 RESULT,我想創建第三列 N_RESULTS_EQUAL_1_PAST_60_DAYS:
DATE RESULT N_RESULTS_EQUAL_1_PREVIOUS_60_DAYS
2018-12-26 23:13:43 00:00 1 0
2019-02-18 23:27:58 00:00 0 1
2019-02-28 15:02:33 00:00 0 0
2019-03-05 18:30:26 00:00 1 0
2019-05-21 14:54:52 00:00 1 0
2019-08-26 14:30:38 00:00 1 0
2019-09-19 15:51:01 00:00 1 1
2019-12-16 17:58:24 00:00 0 0
2021-02-23 03:50:33 00:00 0 0
2021-08-08 22:26:01 00:00 1 0
2021-09-01 18:04:46 00:00 0 1
對于每一行,我想檢查當前行 60 天內的所有前一行,并總結這些前一行有多少 RESULT == 1。我只能想在一個double for 回圈中解決這個問題,效率不高。如果有更有效的方法來解決這個問題?
編輯 1:我在第一次創建 N_RESULTS_EQUAL_1_PREVIOUS_60_DAYS 列時犯了一個錯誤,我沒有考慮 RESULT == 1,我現在正在修復它。
編輯 2:我認為有這個簡單的例子就足以解決問題。然而,事實證明,迄今為止最好的答案要求對日期進行排序,而我實際上無法對日期進行排序,原因如下:
我的實際問題中有一些ID,我必須將這個問題解決到每個單獨的ID。我的 DF 實際上更像這樣:
DATE ID RESULT N_RESULTS_EQUAL_1_PREVIOUS_60_DAYS
2018-01-24 22:02:36 00:00 104 1 0
2018-05-15 18:27:17 00:00 104 0 0
2019-05-15 22:58:06 00:00 104 1 0
2019-07-22 15:17:55 00:00 104 1 0
2020-01-03 20:27:52 00:00 104 1 0
2018-12-26 23:13:43 00:00 105 1 0
2019-02-18 23:27:58 00:00 105 0 1
2019-02-28 15:02:33 00:00 105 0 0
2019-03-05 18:30:26 00:00 105 1 0
2019-05-21 14:54:52 00:00 105 1 0
2019-08-26 14:30:38 00:00 105 1 0
2019-09-19 15:51:01 00:00 105 1 1
2019-12-16 17:58:24 00:00 105 0 0
2021-02-23 03:50:33 00:00 105 0 0
2021-08-08 22:26:01 00:00 105 1 0
2021-09-01 18:04:46 00:00 105 0 1
2019-01-12 21:24:23 00:00 106 0 0
2019-05-28 08:03:55 00:00 106 1 0
2019-09-17 02:56:47 00:00 106 0 0
2020-05-06 17:20:55 00:00 106 0 0
2021-01-07 13:14:41 00:00 106 0 0
所以,如果我將我的 DATE 列設定為索引,然后對我的索引進行排序,我最終會弄亂我的 ID 列。
uj5u.com熱心網友回復:
假設 'DATE' 是一個 DatetimeIndex,您可以按 'ID' 分組,然后使用 .rolling() 現在適用于參差不齊的日期時間:
df['N_RESULTS_EQUAL_1_PREVIOUS_60_DAYS'] = df.groupby('ID').rolling('60D').sum().astype('int').droplevel(0)
我正在使用原始索引在此處添加列,這是可行的,但我認為更強大的解決方案是使用“ID”和“DATE”將原始 df 與包含 60 天總和的 df 合并,所以你也可以試試。另外,我知道您不想包括“結果”本身,而只想包括以前的總和。在這種情況下,只需減去它:
df['N_RESULTS_EQUAL_1_PREVIOUS_60_DAYS'] = df['N_RESULTS_EQUAL_1_PREVIOUS_60_DAYS'] - df['RESULT']
輸出:
DATE ID RESULT N_RESULTS_EQUAL_1_PREVIOUS_60_DAYS
2018-01-24 22:02:36 00:00 104 1 0
2018-05-15 18:27:17 00:00 104 0 0
2019-05-15 22:58:06 00:00 104 1 0
2019-07-22 15:17:55 00:00 104 1 0
2020-01-03 20:27:52 00:00 104 1 0
2018-12-26 23:13:43 00:00 105 1 0
2019-02-18 23:27:58 00:00 105 0 1
2019-02-28 15:02:33 00:00 105 0 0
2019-03-05 18:30:26 00:00 105 1 0
2019-05-21 14:54:52 00:00 105 1 0
2019-08-26 14:30:38 00:00 105 1 0
2019-09-19 15:51:01 00:00 105 1 1
2019-12-16 17:58:24 00:00 105 0 0
2021-02-23 03:50:33 00:00 105 0 0
2021-08-08 22:26:01 00:00 105 1 0
2021-09-01 18:04:46 00:00 105 0 1
2019-01-12 21:24:23 00:00 106 0 0
2019-05-28 08:03:55 00:00 106 1 0
2019-09-17 02:56:47 00:00 106 0 0
2020-05-06 17:20:55 00:00 106 0 0
2021-01-07 13:14:41 00:00 106 0 0
uj5u.com熱心網友回復:
似乎@MethodGuy 已經描述了rolling()我在研究解決方案時如何使用,但我把我的版本放在了因為我還有別的東西。
而且我也得到了與@MethodGuy 相同的結果,它們當時不同,N_RESULTS_EQUAL_1_PREVIOUS_60_DAYS所以我檢查了rolling window.
我不確定,但也許應該是61D(減去函式中的最后日期)才能得到past 60D
如果你想有DATE作為index,那么你可以使用rolling('60D')創建rolling window作業只有過去60天-然后你可以使用.sum(),.count()等你還可以使用.apply(func)運行自己的功能,可以跳過當前的日期
def result(data):
return data[:-1].sum()
df['result'] = df['RESULT'].rolling('60D').apply(result).astype(int)
顯示.sum(), 的最小作業代碼.count(),.apply()用于計算沒有當前日期的總和。我也.apply()用來計算第一個和最后一個日期之間的天數rolling window
text = '''DATE RESULT 60_DAYS
2018-12-26 23:13:43 00:00 1 0
2019-02-18 23:27:58 00:00 0 1
2019-02-28 15:02:33 00:00 0 1
2019-03-05 18:30:26 00:00 1 2
2019-05-21 14:54:52 00:00 1 0
2019-08-26 14:30:38 00:00 1 0
2019-09-19 15:51:01 00:00 1 1
2019-12-16 17:58:24 00:00 0 0
2021-02-23 03:50:33 00:00 0 0
2021-08-08 22:26:01 00:00 1 0
2021-09-01 18:04:46 00:00 0 1'''
import pandas as pd
import io
df = pd.read_csv(io.StringIO(text), sep='\s{2,}')
df.index = pd.to_datetime(df['DATE'])
del df['DATE']
print(df)
def result1(data):
data = data[:-1]
return data.sum()
def result2(data):
data = data[:-1]
return len(data[ data == 1 ])
def days(data):
return (data.index[-1] - data.index[0]).days
window = df['RESULT'].rolling('60D')
df['sum'] = window.sum().astype(int)
df['count'] = window.count().astype(int)
df['result1'] = window.apply(result1).astype(int)
df['result2'] = window.apply(result2).astype(int)
df['days'] = window.apply(days).astype(int)
print(df)
結果:
RESULT 60_DAYS sum count result1 result2 days
DATE
2018-12-26 23:13:43 00:00 1 0 1 1 0 0 0
2019-02-18 23:27:58 00:00 0 1 1 2 1 1 54
2019-02-28 15:02:33 00:00 0 1 0 2 0 0 9
2019-03-05 18:30:26 00:00 1 2 1 3 0 0 14
2019-05-21 14:54:52 00:00 1 0 1 1 0 0 0
2019-08-26 14:30:38 00:00 1 0 1 1 0 0 0
2019-09-19 15:51:01 00:00 1 1 2 2 1 1 24
2019-12-16 17:58:24 00:00 0 0 0 1 0 0 0
2021-02-23 03:50:33 00:00 0 0 0 1 0 0 0
2021-08-08 22:26:01 00:00 1 0 1 1 0 0 0
2021-09-01 18:04:46 00:00 0 1 1 2 1 1 23
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/369044.html
下一篇:如何旋轉Pyspark資料框
