【问题标题】:Algorithmic efficiency of dropping a multitude of rows from a pandas dataframe从 pandas 数据框中删除大量行的算法效率
【发布时间】:2021-12-07 08:05:53
【问题描述】:

我有一个很大的数据框,我从中确定了要删除的索引范围。

为了识别正确的行,我有一个看起来有点像这样的数组:

drop_pairs = [
["2020-01-01 10:00:00","2020-01-03 13:00:00"],
["2020-01-13 11:00:00","2020-01-13 13:33:00"],
["2020-01-22 00:07:00","2020-01-22 22:22:00"],
...]

我正在尝试基于此数组在我的数据框中删除行:

for timerange in drop_pairs:
    df = df.drop(df.loc[f"{timerange[0]}":f"{timerange[1]}"].index)

但是对于大型数据框,这种方法确实非常慢。 我怎样才能提高效率?

【问题讨论】:

  • 只是一个想法,我没有用大 df 尝试过,可能先在索引上执行此操作,然后使用loc 获取您想要的df,而不是在大数据框上操作?
  • 部分问题是您没有数组。如果你这样做了,你可以非常简单地将整个数组转换成一个布尔掩码,并且只是这样子集。
  • 您好,欢迎您。如果您可以查看How to Ask,然后尝试生成minimal reproducible example,那就太好了。

标签: python pandas dataframe indexing drop


【解决方案1】:

正如 cmets 中所暗示的,这也可以使用布尔数组来完成。我已将数组drop_pairs 转换为两个数组drop_startsdrop_ends,并分别对应要删除的时间范围的开始值和结束值。

接下来,我创建了面具:

mask_starts = df.index.isin(drop_starts).astype(int)
mask_ends = df.index.isin(drop_ends).astype(int) * -1

这样mask_starts + mask_ends 将给出一个数组,该数组的长度与我的df 相同,其中要删除的时间范围开始时为 1s,结束时为 -1s,其他地方为 0s。

我随后使用np.cumsum 将所有要删除的时间戳标记为 1,将其他所有时间戳标记为 0。

drop_mask = np.cumsum(mask_starts + mask_ends)

基于此掩码,很容易删除相关范围:

df = df[~drop_mask.astype(bool)]

【讨论】:

    猜你喜欢
    • 2023-01-31
    • 1970-01-01
    • 2023-02-07
    • 2021-06-18
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    相关资源
    最近更新 更多