python-根据来自另一个数据框2的值(时间)范围提取数据框1的值

时间:2018-07-27 23:06:37

标签: python pandas dataframe

我正在尝试使用vlookup在excel上做似乎很容易的事情。一直以来都是timedelta datatype。通过Google搜索错误找不到适合我的解决方案。

DF1 (bellow)是我的主要DataFrame,其中一个值为到达时间。

+--------+------+
|Arrival | idBin|
+--------+------+
|10:01:40|  nan |
|10:03:12|  nan |
|10:05:55|  nan |
|10:05:10|  nan |
+--------+------+

DF2(bellow)是我的参数数据框,具有 1k +时间范围(手动创建字典似乎不切实际)。

+--------+--------+------+
|start   |end     |idBin |
+--------+--------+------+
|10:00:00|10:00:30|  1   |
|10:00:31|10:01:00|  2   |
|10:01:01|10:01:30|  3   |
|10:01:31|10:02:00|  4   |
+--------+--------+------+

我需要将DF2.idBin放入DF1.idBin,其中DF1.arrivalDF2.startDF2.end之间

到目前为止我尝试过的事情:

**.loc**>返回ValueError: Can only compare identically-labeled Series objects

    pd.DataFrame.loc[ (df1['arrival'] >= df2['start']) 
                     & (df1['arrival'] <= df2['end']), 'idBin'] = df2['idBin']

**date_range()**,所以我可以将其转换为字典,但返回TypeError: Cannot convert input [0 days 10:00:00] of type <class 'pandas._libs.tslibs.timedeltas.Timedelta'> to Timestamp

dt_range = pd.date_range(start=df2['start'].min(), end=df2['end'].max(), name=df2['idBin'])

3 个答案:

答案 0 :(得分:0)

DF2_intervals = pd.Series(DF2['idBin'], pd.IntervalIndex.from_arrays(DF2['start'], DF2['end']))
DF1['idBin'] = DF1['Arrival'].map(DF2_intervals)

如果需要,您还可以将其转换为一行以提高效率。

让我知道是否可行。

答案 1 :(得分:0)

我不确定是否有预先构建的解决方案,但是您可以执行与尝试的操作类似的操作,但是在UDF中将其应用于df1中的列,并输出新的列。

def match_idbin(date, df2):
    idbin = df2.loc[(df2['start'] > date)&
                (df2['end'] < date),'idBin']
    return idbin

df1['idBin'] = df1['Arrival'].apply(lambda x: match_idbin(x, df2))

答案 2 :(得分:0)

IIUC

x = pd.Series(df2['idBin'], pd.IntervalIndex.from_arrays(df2['start'], df2['end']))
inds = np.array([np.flatnonzero(np.array([k in z for z in x.index])) for k in df.Arrival])
bools = [arr.size>0 for arr in inds]
df.loc[bools, 'idBin'] = df2.iloc[[ind[0] for ind in inds[bools]]].idBin.values