【问题标题】:More efficient alternative to nested For loop嵌套 For 循环的更有效替代方案
【发布时间】:2020-12-10 14:01:33
【问题描述】:

我有两个数据框,其中包含以两种不同频率收集的数据。 如果它属于事件的持续时间,我想将 df2 的标签更新为 df1 的标签。

我创建了一个嵌套的 for 循环来执行此操作,但这需要相当长的时间。 这是我使用的代码:

for i in np.arange(len(df1)-1):
    for j in np.arange(len(df2)):
        if (df2.timestamp[j] > df1.timestamp[i]) & (df2.timestamp[j] < (df1.timestamp[i] + df1.duration[i])):
            df2.loc[j,"label"] = df1.loc[i,"label"]

有没有更有效的方法来做到这一点? df1 尺寸 (367, 4) df2 大小 (342423, 9)

简短的示例数据:

import numpy as np
import pandas as pd

data1 = {'timestamp':  [1,2,3,4,5,6,7,8,9],
    'duration': [0.5,0.3,0.8,0.2,0.4,0.5,0.3,0.7,0.5],
     'label': ['inh','exh','inh','exh','inh','exh','inh','exh','inh']
    }
df1 = pd.DataFrame (data1, columns = ['timestamp','duration','label'])

data2 = {'timestamp':  [1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5,8,8.5,9,9.5],
         'label': ['plc','plc','plc','plc','plc','plc','plc','plc','plc','plc','plc','plc','plc','plc','plc','plc','plc','plc']
        }
    df2 = pd.DataFrame (data2, columns = ['timestamp','label'])

【问题讨论】:

  • 如果你能提供一个minimal reproducible example,那就更好了。
  • 酷,从您的示例代码中,我假设用于多个匹配的逻辑,即如果df2 中的一行与df1 中的多个匹配,则取最后一个(按索引顺序)?
  • df2 中的一行不应匹配 df1 中的多行,因为 df2 中的事件没有持续时间/持续时间=0。但是,df2 中的多行可以匹配 df1 中的一行,在这种情况下,它们会得到相同的标签。

标签: python performance for-loop nested


【解决方案1】:

我将首先使用merge_asof 来选择 df1 中的最高时间戳,该时间戳低于 df2 中的时间戳。接下来对 df2.timestamp 和 df1.timestamp + df1.duration 进行简单(矢量化)比较就足以选择匹配行。

代码可以是:

df1['t2'] = df1['timestamp'].astype('float64') # types of join columns must be the same
temp = pd.merge_asof(df2, df1, left_on='timestamp', right_on='t2')
df2.loc[temp.timestamp_x <= temp.t2 + temp.duration, 'label'] = temp.label_y

它为 df2 提供:

    timestamp label
0         1.0   inh
1         1.5   inh
2         2.0   exh
3         2.5   plc
4         3.0   inh
5         3.5   inh
6         4.0   exh
7         4.5   plc
8         5.0   inh
9         5.5   plc
10        6.0   exh
11        6.5   exh
12        7.0   inh
13        7.5   plc
14        8.0   exh
15        8.5   exh
16        9.0   inh
17        9.5   inh

【讨论】:

  • 't2'代表什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-09
  • 2020-01-15
  • 2015-06-29
  • 2018-04-15
  • 2019-10-11
  • 2023-01-17
相关资源
最近更新 更多