Python 在给定条件下向数据帧添加值

Python 在给定条件下向数据帧添加值,python,pandas,dataframe,Python,Pandas,Dataframe,我一直在努力找到最有效的方法。 假设我有一个数据帧df1,看起来像: time_start time_end 0 1548102229 1548102232 1 1548102239 1548102242 2 1548102249 1548102252 3 1548102259 1548102262 timestamp state 0 1548102231 A 1 1548102241 A 2 1548102248 B

我一直在努力找到最有效的方法。 假设我有一个数据帧df1,看起来像:

   time_start  time_end    
0  1548102229  1548102232  
1  1548102239  1548102242 
2  1548102249  1548102252
3  1548102259  1548102262
   timestamp   state    
0  1548102231  A  
1  1548102241  A 
2  1548102248  B
3  1548102251  B
另一个数据帧df2看起来像:

   time_start  time_end    
0  1548102229  1548102232  
1  1548102239  1548102242 
2  1548102249  1548102252
3  1548102259  1548102262
   timestamp   state    
0  1548102231  A  
1  1548102241  A 
2  1548102248  B
3  1548102251  B
如果df2['timestamp']介于df1['time\u start']和df1['time\u end']之间,则有没有一种方法可以将“state”添加到df1,以达到:

   time_start  time_end    state
0  1548102229  1548102232  A
1  1548102239  1548102242  A
2  1548102249  1548102252  N/A
3  1548102259  1548102262  B

使用
IntervalIndex
get\u indexer
,然后我们在
之后分配回.loc

idx=pd.IntervalIndex.from_arrays(df1['time_start'], df1['time_end'], closed='both')
indexmatch=idx.get_indexer(df2.timestamp)
df1['New']=df2.loc[indexmatch,'state'].values
df1
   time_start    time_end  New
0  1548102229  1548102232    A
1  1548102239  1548102242    A
2  1548102249  1548102252  NaN
3  1548102259  1548102262    B
更新

idx=pd.IntervalIndex.from_arrays(df1['time_start'], df1['time_end'], closed='both')
indexmatch=idx.get_indexer(df2.timestamp)
dfcopy=df1.copy()
df1=df1.loc[indexmatch]
df1['New']=df2.loc[indexmatch,'state'].values
df1.groupby(['time_start','time_end'],as_index=False).New.sum().combine_first(dfcopy)
使用和
outer
ufuncs

c = np.less_equal.outer(df2.timestamp, df.time_end) & \
    np.greater_equal.outer(df2.timestamp, df.time_start)

df['state'] = df2.state.values[c.argmax(1)]
然后更正所有
False
结果

df.loc[~c.any(1), 'state'] = np.nan

    time_start  time_end    state
0   1548102229  1548102232  A
1   1548102239  1548102242  A
2   1548102249  1548102252  NaN
3   1548102259  1548102262  B

这是一个很好的问题,我实际上没有遇到过这种情况,但它最终肯定会发生。如果是这样的话,我想取第一个状态。如果df2的长度与df1不同,并且我试图找出df2中是否有一个时间戳介于时间开始和时间结束之间的值来填充df1中的状态,该怎么办?我确信,在任何给定的时间段内,只有一种状态存在,即A或B,但该状态可以被记录多次。这已经非常接近了。我对最后一行只有一个问题:df1.groupby(['time\u start','time\u end',as\u index=False)。New.sum()。combine\u first(dfcopy)sum()部分给了我一个意外的结果。如果df1['New']是一个整数,则它将状态与数量或发生次数相加。如果它是一个字符串,它会进行字符串求和,所以如果有超过1个记录状态,它会给我像AAA这样的值,如果字符串或如果状态a=1,它会给我3。尝试不使用求和,但似乎combine_first不喜欢它。没关系,我只是完成了df1.groupby(['time_start','time_end',as_index=False)。first()我认为combine_first(dfcopy)没有必要。我猜您的方法的问题是相同的:如果df2的长度与df1不同,并且我试图找出df2中是否有一个时间戳介于时间开始和时间结束之间的值来填充df1中的状态,该怎么办?我确信,在任何给定的时间段内,只有一种状态存在,即A或B,但该状态可以被记录多次。