I have a unique requirement around time-series analysis and have presented my requirements along with a simple working solution. I have also worked out sample example to help understand my requirements.I am seeking help with regards to making this code efficient in terms of:Reducing time and space complexityReducing lines of code if any of these can be achieved by using in-built functions in Pandas or other Python librariesConsider following time-series data for example:import pandas as pddf1 = pd.DataFrame({'Date': {0: '2016-10-11', 1: '2016-10-11', 2: '2016-10-11', 3: '2016-10-11', 4: '2016-10-11',5: '2016-10-11'}, 'Stock': {0: 'ABC', 1: 'ABC', 2: 'ABC', 3: 'ABC', 4: 'ABC', 5: 'XYZ'}, 'StartTime': {0: '08:00:00.241', 1: '08:00:00.243', 2: '12:34:23.563', 3: '08:14.05.908', 4: '18:54:50.100', 5: '10:08:36.657'}, 'EndTime': {0: '09:13:46.867',1: '10:06:26.452', 2: '12:34:23.569', 3: '11:24:23.533', 4: '18:55:23.903', 5: '14:51:08.756'}})df2 = pd.DataFrame({'Date': {0: '2016-10-11', 1: '2016-10-11', 2: '2016-10-11', 3: '2016-10-11', 4: '2016-10-11'}, 'Stock': {0: 'ABC', 1: 'ABC', 2: 'ABC', 3: 'ABC', 4: 'ABC'}, 'Volume': {0: 100, 1: 300, 2: 600, 3: 1500, 4: 200}, 'Price': {0: 10.05, 1: 10.10, 2: 10.40, 3:10.50, 4: 10.45}, 'time': {0: '08:00:00.242', 1: '09:00:10.534', 2: '10:08:36.658', 3: '11:45:43.654', 4: '12:34:23.563'}})print df1print df2         Date       EndTime     StartTime Stock0  2016-10-11  09:13:46.867  08:00:00.241   ABC1  2016-10-11  10:06:26.452  08:00:00.243   ABC2  2016-10-11  12:34:23.569  12:34:23.563   ABC3  2016-10-11  11:24:23.533  08:14:05.908   ABC4  2016-10-11  18:55:23.903  18:54:50.100   ABC5  2016-10-11  14:51:08.756  10:08:36.657   XYZ         Date   Price Stock  Volume          time0  2016-10-11   10.05   ABC     100  08:00:00.2421  2016-10-11   10.10   ABC     300  09:00:10.5342  2016-10-11   10.40   ABC     600  10:08:36.6583  2016-10-11   10.50   ABC    1500  11:45:43.6544  2016-10-11   10.45   ABC     200  12:34:23.563I have written the function make_join below. For this function I am seeking help with regards to make it efficient in following aspects:Reducing time and space complexityReducing lines of code if any of these can be achieved by using in-built functions in Pandas or other Python librariesThe function looks as follows:def make_join(df1, df2, left_time, right_time, left_on, right_on, uptoRows=2, isAsOf=True):    Joins DataFrame df2 to DataFrame df1 asOf/onAfter left_time and right_time by making inner join on left_on and right_on.   Fetches <= uptoRows eligible rows from df2. Retains original column names and order in df1.     # Do inner join on non-time join-columns.  df3 = df1.merge(df2, left_on = left_on, right_on = right_on)  # Delete repeated join columns from df3  for lcol, rcol in zip(left_on, right_on):      if lcol <> rcol: df3.drop(rcol, axis = 1, inplace = True)  # Un-rename df1 common columns from df3  df2Cols = list(df2.columns)  for col in list(df1.columns):      if col in df2Cols: df3.rename(columns={col + '_x': col}, inplace = True)  # Rename right_time if it is same as left_time.  if left_time == right_time: right_time += '_y'  # Applying Asof/OnAfter criteria and selecting uptoRows  if isAsOf:      df3 = df3.loc[df3[right_time] <= df3[left_time]]      df3 = df3.sort_values(right_time, ascending = True).groupby(list(df1.columns)).tail(uptoRows)  else:      df3 = df3.loc[df3[right_time] >= df3[left_time]]      df3 = df3.sort_values(right_time, ascending = True).groupby(list(df1.columns)).head(uptoRows)  # Including df1 records for which no match was found and restoring original ordering of df1.  return df1.merge(df3, on = list(df1.columns), how = 'outer')The first run of this function with isAsOf=True produces following correct output:df4 = make_join(df1, df2, left_time='StartTime', right_time='time', left_on=['Date','Stock'], right_on=['Date','Stock'], isAsOf=True)print df4         Date       EndTime     StartTime Stock  Price  Volume          Time0  2016-10-11  09:13:46.867  08:00:00.241   ABC    NaN     NaN           NaN1  2016-10-11  10:06:26.452  08:00:00.243   ABC  10.05     100  08:00:00.2422  2016-10-11  12:34:23.569  12:34:23.563   ABC  10.50    1500  11:45:43.6543  2016-10-11  12:34:23.569  12:34:23.563   ABC  10.45     200  12:34:23.5634  2016-10-11  11:24:23.533  08:14.05.908   ABC  10.05     100  08:00:00.2425  2016-10-11  18:55:23.903  18:54:50.100   ABC  10.50    1500  11:45:43.6546  2016-10-11  18:55:23.903  18:54:50.100   ABC  10.45     200  12:34:23.5637  2016-10-11  14:51:08.756  10:08:36.657   XYZ    NaN     NaN           NaNThe second run of the function with isAsOf=False produces following correct output:df4 = make_join(df1, df2, left_time='StartTime', right_time='time', left_on=['Date','Stock'], right_on=['Date','Stock'], isAsOf=False)print df4         Date       EndTime     StartTime Stock  Price  Volume          Time0  2016-10-11  09:13:46.867  08:00:00.241   ABC  10.05     100  08:00:00.2421  2016-10-11  09:13:46.867  08:00:00.241   ABC  10.10     300  09:00:10.5342  2016-10-11  10:06:26.452  08:00:00.243   ABC  10.10     300  09:00:10.5343  2016-10-11  10:06:26.452  08:00:00.243   ABC  10.40     600  10:08:36.6584  2016-10-11  12:34:23.569  12:34:23.563   ABC  10.45     200  12:34:23.5635  2016-10-11  11:24:23.533  08:14.05.908   ABC  10.10     300  09:00:10.5346  2016-10-11  11:24:23.533  08:14.05.908   ABC  10.40     600  10:08:36.6587  2016-10-11  18:55:23.903  18:54:50.100   ABC    NaN     NaN           NaN8  2016-10-11  14:51:08.756  10:08:36.657   XYZ    NaN     NaN           NaN
Cross-join time-series using asof criteria while limiting number of rows
python;pandas;join