假設您有一個可以使用以下代碼創建的 Pandas 資料框:
test_df = pd.DataFrame(
{'start_date': ['2021-07-01', '2021-07-02', '2021-07-03',
'2021-07-04', '2021-07-05', '2021-07-06'],
'end_date': ['2021-07-03', '2021-07-04', '2021-07-05',
'2021-07-06', '2021-07-07', '2021-07-08'],
'returns': [1, 1, 0.99, 0.98, 0.99, 0.97]})
test_df = test_df.sort_values('returns', ascending=False)
假設returns總是排序什么是洗掉重疊間隔的有效方法?我不想使用回圈,因為資料集很大是否有矢量化方法來實作下面的輸出?
預期產出
------------ ------------ ---------
| start_date | end_date | returns |
------------ ------------ ---------
| 2021-07-01 | 2021-07-03 | 1 |
| 2021-07-05 | 2021-07-07 | 0.99 |
------------ ------------ ---------
uj5u.com熱心網友回復:
@mozway這里有一個答案,它可以通過使用np.triu()(numpy 的上三角形)在沒有回圈的情況下作業。
為您的 DataFrame 稍微更改它:
import numpy as np
test_df["start_date"] = pd.to_datetime(test_df["start_date"])
test_df["end_date"] = pd.to_datetime(test_df["end_date"])
a = np.triu(test_df['end_date'].values > test_df['start_date'].values[:, None])
b = np.triu(test_df['start_date'].values < test_df['end_date'].values[:, None])
test_df[(a & b).sum(0) == 1]
# start_date end_date returns
#0 2021-07-01 2021-07-03 1.00
#4 2021-07-05 2021-07-07 0.99
解釋:
test_df['end_date'].values > test_df['start_date'].values[:, None]
#array([[ True, True, True, True, True, True],
# [ True, True, True, True, True, True],
# [False, True, True, True, True, True],
# [False, False, False, True, True, True],
# [False, False, True, True, True, True],
# [False, False, False, True, False, True]])
這將回傳一個陣列,其中 end_date 值大于 start_date 值。這會查看開始日期和結束日期的每個組合(每個結束日期作為一列,每個開始日期作為一行。如果滿足條件,則True回傳。
取上面的三角形意味著只有開始日期與結束日期一起或在結束日期之前的組合(就test_df行而言)是True,其余的False
b另一方面,查找結束日期大于開始日期的所有實體(每個開始日期為一列,每個結束日期為一行)。對于 的第一行test_df['start_date'].values < test_df['end_date'].values[:, None],它正在查看第一個結束日期的組合2021-07-03以及它是否大于開始日期。
上面的三角形意味著只有開始日期在資料框中的結束日期之前出現的情況是True.
解構最后一行test_df[(a & b).sum(0) == 1]:
(a & b)是一個陣列,True其中兩個陣列都出現True。(a & b).sum(0)對該陣列的每一列求和,其中True == 1和False == 0。(a & b).sum(0) == 1是只有一次出現a并在一起b的行。True我們只想要這些,因為我們想要以下行:
- 開始日期小于上一個(或當前)結束日期
和
- 結束日期大于前一個(或當前)開始日期
然而
如果這種情況不止一次發生,那么一定有重疊。因為在這種情況下,前導對角線總是True(因為給定資料框行的結束日期必須總是大于開始日期),如果這種情況發生不止一次,這意味著:
- 開始日期小于上一個結束日期和當前結束日期
和
- 結束日期大于前一個開始日期和當前開始日期
這意味著這里必須有重疊。
我知道這很令人困惑,但確實有道理!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/474489.html
