2015-07-09 2 views
3

У меня есть две панды dataframes: один (df1) с тремя колонками (StartDate, EndDate и ID) и второй (df2) с датой. Я хочу объединить df1 и df2 на основе df2.Date между df1.StartDate и df2.EndDate.Объединения dataframes на основе диапазона дат

Каждый диапазон дат в df1 уникален и не пересекается ни с одной из других строк в кадре данных.

Даты отформатированы YYYY-MM-DD.

+1

Вы должны определить FUNC для выполнения поиска, 'merge' не выполнит матч для вас, как это требуется точное совпадение по значению, а не между диапазонами – EdChum

+1

Показать похожие: HTTP: // StackOverflow. com/questions/21367485/merge-pandas-dataframes-on-irregular-time-interval? rq = 1 – EdChum

+0

Не могли бы вы принять мой ответ, если это поможет вам решить вопрос? Большое спасибо. :-) –

ответ

9

Просто, чтобы предоставить альтернативный способ, используя np.piecewise. Производительность еще быстрее, чем np.searchedsort.

import pandas as pd 
import numpy as np 

# data 
# ==================================== 
df1 = pd.DataFrame({'StartDate': pd.date_range('2010-01-01', periods=9, freq='5D'), 'EndDate': pd.date_range('2010-01-04', periods=9, freq='5D'), 'ID': np.arange(1, 10, 1)}) 

df2 = pd.DataFrame(dict(values=np.random.randn(50), date_time=pd.date_range('2010-01-01', periods=50, freq='D'))) 

df1.StartDate 

Out[139]: 
0 2010-01-01 
1 2010-01-06 
2 2010-01-11 
3 2010-01-16 
4 2010-01-21 
5 2010-01-26 
6 2010-01-31 
7 2010-02-05 
8 2010-02-10 
Name: StartDate, dtype: datetime64[ns] 

df2.date_time 

Out[140]: 
0 2010-01-01 
1 2010-01-02 
2 2010-01-03 
3 2010-01-04 
4 2010-01-05 
5 2010-01-06 
6 2010-01-07 
7 2010-01-08 
8 2010-01-09 
9 2010-01-10 
     ...  
40 2010-02-10 
41 2010-02-11 
42 2010-02-12 
43 2010-02-13 
44 2010-02-14 
45 2010-02-15 
46 2010-02-16 
47 2010-02-17 
48 2010-02-18 
49 2010-02-19 
Name: date_time, dtype: datetime64[ns] 


df2['ID_matched'] = np.piecewise(np.zeros(len(df2)), [(df2.date_time.values >= start_date)&(df2.date_time.values <= end_date) for start_date, end_date in zip(df1.StartDate.values, df1.EndDate.values)], df1.ID.values) 


Out[143]: 
    date_time values ID_matched 
0 2010-01-01 -0.2240   1 
1 2010-01-02 -0.4202   1 
2 2010-01-03 0.9998   1 
3 2010-01-04 0.4310   1 
4 2010-01-05 -0.6509   0 
5 2010-01-06 -1.4987   2 
6 2010-01-07 -1.2306   2 
7 2010-01-08 0.1940   2 
8 2010-01-09 -0.9984   2 
9 2010-01-10 -0.3676   0 
..  ...  ...   ... 
40 2010-02-10 0.5242   9 
41 2010-02-11 0.3451   9 
42 2010-02-12 0.7244   9 
43 2010-02-13 -2.0404   9 
44 2010-02-14 -1.0798   0 
45 2010-02-15 -0.6934   0 
46 2010-02-16 -2.3380   0 
47 2010-02-17 1.6623   0 
48 2010-02-18 -0.2754   0 
49 2010-02-19 -0.7466   0 

[50 rows x 3 columns] 

%timeit df2['ID_matched'] = np.piecewise(np.zeros(len(df2)), [(df2.date_time.values >= start_date)&(df2.date_time.values <= end_date) for start_date, end_date in zip(df1.StartDate.values, df1.EndDate.values)], df1.ID.values) 
1000 loops, best of 3: 466 µs per loop 
+0

Jianxun, спасибо за ответ. Есть ли способ сделать это с помощью 'datetime64' Series в pandas DataFrames? –

+0

@NicholasTulach Я думаю, что pandas будет рассматривать datetime как datetime64 как поведение по умолчанию. поэтому он должен работать и с серией datetime64. если вы видите какую-либо ошибку, не могли бы вы загрузить ваш образец файла данных через sharebox с Dropbox, чтобы я мог посмотреть, что может пойти не так. –

+0

@NicholasTulach, если вы запустите приведенный выше пример кода, вы можете проверить dtype индекса, это datetime64. –

Смежные вопросы