首页 > 解决方案 > 标记 df 中时间范围重叠的条目

问题描述

我有一个 df 以下 df_test

df_test = pd.DataFrame(np.array([[1, 10, 20], [1, 5, 8], [1, 5, 15], [1, 13, 14], [1, 18, 21],[2, 2, 2], [1, 21, 100], [1, 1, 50]]),
                   columns=['id', 'charging_start_in_ms', 'charging_stop_in_ms'])
df_test['valid'] = True

print(f"{df_test} \n")
>>> id  charging_start_in_ms    charging_stop_in_ms valid
  0 1   10                      20                  True
  1 1   5                       8                   True
  2 1   5                       15                  True
  3 1   13                      14                  True
  4 1   18                      21                  True
  5 2   2                       2                   True
  6 1   21                      100                 True
  7 1   1                       50                  True

我正在寻找一种有效的方法来标记无效的条目,这些条目具有

  1. 相同的身份证
  2. 时间重叠

我走了这么远:

col2 = 'id'
col3 = 'charging_start_in_ms'
col4 = 'charging_stop_in_ms'

for index, row in df_test.iterrows():
    id = df_test.at[index, col2]
    start = df_test.at[index, col3]
    stop = df_test.at[index, col4]

    #sort out transaction with different id
    df_temp = df_test[df_test[col2] == id]
    #sort out transactions before
    df_temp = df_temp[~((df_temp[col3] < start) & (df_temp[col4] < start))]
    #sort out transactions after
    df_temp = df_temp[~((df_temp[col3] > stop) & (df_temp[col4] > stop))] 

    #print(f"Index: {index}")
    #print(df_temp)

    for index in df_temp.index:
        df_test.loc[index, 'valid'] = False
            
df_test
>>> id  charging_start_in_ms    charging_stop_in_ms valid
  0 1   10                      20                  False
  1 1   5                       8                   False
  2 1   5                       15                  False
  3 1   13                      14                  False
  4 1   18                      21                  False
  5 2   2                       2                   False
  6 1   21                      100                 False
  7 1   1                       50                  False

我的问题是,我也总是选择观察到的项目,所以最后所有项目都设置为valid=False,但我希望item id=2 是valid=True。在保留选项的情况下,我如何管理这一点,即不同的项目可能具有相同的 id 和准确的charging_start_in_ms 和/或charging_stop_in_ms。

有什么提示吗?谢谢

编辑:我添加了这个来删除索引

#sort out same index
df_temp = df_test.drop([index]) 

编辑二:另一个可行的解决方案是:

    #3 cases for overlapping charging time
    #case 1: index.start <= stop <= index.stop
    #case 2: index.start <= start <= index.stop
    #case 3: start <= index start and stop >= index.stop
    df_temp = df.query(f"{col2} == '{id}' and (({start} <= {col4} <= {stop}) or ({start} <= {col3} <= {stop}) or ({col3} <= {start} and {col4} >= {stop}))")
    #sort out same index
    df_temp = df_temp.drop([index])

我想它有效,但下一个问题是,我的整体数据的 0.01% 需要大约 6 秒。因此,如果我进行插值,它将需要大约 100 分钟(对于 326000 个条目)。有没有更快的解决方案?

标签: python-3.xdataframe

解决方案


一个快速而肮脏的解决方案是跳过内部 for 循环中的目标索引,例如

for ii in df_temp.index:
    if ii == index:
        continue
df_test.loc[index, 'valid'] = False

它会产生这个输出

>>> df_test
   id  charging_start_in_ms  charging_stop_in_ms  valid
0   1                    10                   20  False
1   1                     5                    8  False
2   1                     5                   15  False
3   1                    13                   14  False
4   1                    18                   21  False
5   2                     2                    2   True
6   1                    21                  100  False
7   1                     1                   50  False

推荐阅读