IT干货网

python之在 Pandas 中找到区间的交集

zhengyun_ustc 2025年01月19日 编程设计 77 0

我有两个数据框

df_a= 
 
     Start Stop Value 
    0  0     100  0.0 
    1  101   200  1.0 
    2  201  1000  0.0 
 
df_b= 
       Start Stop Value 
    0  0     50 0.0 
    1  51   300 1.0 
    2  301 1000  0.0 

我想生成一个 DataFrame其中包含由 Start 标识的区间和 Stop ,其中值在 df_a 中相同和df_b。对于我想存储的每个间隔:if Value是相同的,这是 df_a 中的值和 df_b .
期望的输出:
df_out= 
  Start Stop SameValue Value_dfA Value_dfB 
      0    50    1          0       0 
      51   100   0          0       1 
      101  200   1          1       1 
      201  300   0          0       1 
    [...] 

请您参考如下方法:

不确定这是否是最好的方法,但您可以 reindex , join , groupbyagg获取您的时间间隔,例如:

展开各df以便索引是使用 Start 的范围( Stopreindex() )的每个值和 pad定值:

In []: 
df_a_expanded = df_a.set_index('Start').reindex(range(max(df_a['Stop'])+1)).fillna(method='pad') 
df_a_expanded 
 
Out[]: 
         Stop  Value 
Start                
0       100.0    0.0 
1       100.0    0.0 
2       100.0    0.0 
3       100.0    0.0 
4       100.0    0.0 
... 
997    1000.0    0.0 
998    1000.0    0.0 
999    1000.0    0.0 
1000   1000.0    0.0 
 
[1001 rows x 2 columns] 
 
In []: 
df_b_expanded = df_b.set_index('Start').reindex(range(max(df_b['Stop'])+1)).fillna(method='pad') 

加入两个扩展 dfs :
In []: 
df = df_a_expanded.join(df_b_expanded, lsuffix='_dfA', rsuffix='_dfB').reset_index() 
df 
 
Out[]: 
      Start  Stop_dfA  Value_dfA  Stop_dfB  Value_dfB 
0         0     100.0        0.0      50.0        0.0 
1         1     100.0        0.0      50.0        0.0 
2         2     100.0        0.0      50.0        0.0 
3         3     100.0        0.0      50.0        0.0 
4         4     100.0        0.0      50.0        0.0 
... 

注意:您可以忽略 Stop列,并且可以在上一步中删除它们。
groupby没有标准的方法只有连续的值(à la itertools.groupby ),所以求助于 cumsum()黑客:
In []: 
groups = (df[['Value_dfA', 'Value_dfB']] != df[['Value_dfA', 'Value_dfB']].shift()).any(axis=1).cumsum() 
g = df.groupby([groups, 'Value_dfA', 'Value_dfB'], as_index=False) 

现在您可以通过将组与 min 聚合来获得您想要的结果。 , max :
In []: 
df_out = g['Start'].agg({'Start': 'min', 'Stop': 'max'}) 
df_out 
 
Out[]: 
   Value_dfA  Value_dfB  Start  Stop 
0        0.0        0.0      0    50 
1        0.0        1.0     51   100 
2        1.0        1.0    101   200 
3        0.0        1.0    201   300 
4        0.0        0.0    301  1000 

现在你只需要添加 SameValue列,如果需要,对列进行排序以获得所需的确切输出:
In []: 
df_out['SameValue'] = (df_out['Value_dfA'] == df_out['Value_dfB'])*1 
df_out[['Start', 'Stop', 'SameValue', 'Value_dfA', 'Value_dfB']] 
 
Out[]: 
   Start  Stop  SameValue  Value_dfA  Value_dfB 
0      0    50          1        0.0        0.0 
1     51   100          0        0.0        1.0 
2    101   200          1        1.0        1.0 
3    201   300          0        0.0        1.0 
4    301  1000          1        0.0        0.0 

这假设两个数据帧的范围相同,否则您将需要处理 NaN您将通过 join() 获得.


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!