簡體   English   中英

Pandas DataFrame在兩個值之間合並而不是匹配一個

[英]Pandas DataFrame merge between two values instead of matching one

我有一個帶有日期列的數據框,我想將其與另一個合並,但不要在該列的匹配項上合並,但是如果日期列在第二個數據框的兩個列之間。

我相信我可以通過在這些准則的基礎上對第二個准則應用過濾器來過濾第二個准則,然后組合結果來實現這一點,但實際上,應用准則是處理問題的極其緩慢的方法。

有沒有一種方法可以將匹配合並為BETWEEN而不是完全匹配。

示例數據框:

,Code,Description,BeginDate,EndDate,RefSessionTypeId,OrganizationCalendarId
0,2014-2015,School Year: 2014-2015,2014-08-18 00:00:00.000,2015-08-01 00:00:00.000,1,3
1,2012-2013,School Year: 2012-2013,2012-09-01 00:00:00.000,2013-08-16 00:00:00.000,1,2
2,2013-2014,School Year: 2013-2014,2013-08-19 00:00:00.000,2014-08-17 00:00:00.000,1,1

而不是在date = BeginDate或date = EndDate合並,我想在日期BETWEEN(BeginDate,EndDate)上進行匹配

您可以使用numpy.searchsorted()模擬BETWEEN

說您的數據和查找值如下所示:

In [162]: data = pd.DataFrame({
   .....:     'Date': pd.Series(pd.np.random.randint(1429449000, 1429649000, 1000) * 1E9).astype('datetime64[ns]'),
   .....:     'Value': pd.np.random.randint(0, 100, 1000),
   .....: })

In [163]: data.head()
Out[163]:
                 Date  Value
0 2015-04-21 13:37:37     60
1 2015-04-20 06:27:43     76
2 2015-04-20 09:01:51     70
3 2015-04-21 10:47:31      5
4 2015-04-19 18:39:45     27

In [164]:

In [164]: lookup = pd.Series(
   .....:     pd.np.random.randint(0, 10, 5),
   .....:     index=pd.Series(pd.np.random.randint(1429449000, 1429649000, 5) * 1E9).astype('datetime64[ns]'),
   .....: )

In [165]: lookup
Out[165]:
2015-04-21 11:10:39    4
2015-04-21 07:07:51    1
2015-04-20 08:27:19    1
2015-04-21 09:58:42    6
2015-04-20 06:46:12    7
dtype: int32

您首先要確保data['Date']中的所有日期在lookup的索引中均可用。 然后,按日期對查找進行排序。

In [166]: lookup[data['Date'].max()] = lookup[data['Date'].min()] = None

In [167]: lookup = lookup.sort_index()

現在是重要的一環-使用NumPy的極其快速的searchsorted()方法來獲取索引:

In [168]: indices = pd.np.searchsorted(lookup.index.astype(long), data['Date'].astype(long).values, side='left')

In [169]: data['Lookup'] = lookup.iloc[indices].values

In [170]: data.head()
Out[170]:
                 Date  Value Lookup
0 2015-04-21 13:37:37     60   None
1 2015-04-20 06:27:43     76      7
2 2015-04-20 09:01:51     70      1
3 2015-04-21 10:47:31      5      4
4 2015-04-19 18:39:45     27      7

編輯:您可能希望將數據集中的日期范圍轉換為單個系列,例如上面的lookup 這是因為在日期范圍重疊的情況下,並不總是清楚要查找哪個值。

最后我意識到我在考慮這個問題,我在兩個表中都添加了一個名為merge的列,而該列只是全1

那么我可以在該列上進行合並,並對合並后的表格進行常規的布爾過濾。

a["merge"] = 1
b["merge"] = 1
c = a.merge(b, on="merge")

然后在c上過濾

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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