【问题标题】:Is there a more efficient way to use two for loops in python?有没有更有效的方法在 python 中使用两个 for 循环?
【发布时间】:2022-01-07 16:36:21
【问题描述】:

我听说在另一个中使用两个 for 循环需要很长时间。但是,我不确定如何解决这个问题。我的每个 for 循环都是 ~40,000 循环,所以时间很长。我基本上是在尝试比较两个 DataFrame 的条目。如果某行中的三个条目(帧、x 和 y)在两者之间匹配,那么我想将其保存到新的数据数组中。我的最终结果是有一个带有帧、x、y、粒子#和两个不同强度的数据框)。我相信我正在做的事情会奏效,但需要 5 个多小时才能得到结果。无论如何我可以让这段代码更快更高效吗?非常感谢,我的代码贴在下面。

intensity = np.zeros((tracks.shape[0], 2))
location = np.zeros((tracks.shape[0], 2))
frame = np.zeros((tracks.shape[0], 1))
particle = np.zeros((tracks.shape[0], 1))

for r in range(red_masked_tracks.shape[0]):
    for g in range(green_masked_tracks.shape[0]):
        if red_masked_tracks['frame'][r] == green_masked_tracks['frame'][g]:
            if round(red_masked_tracks['x'][r]) == round(green_masked_tracks['x'][g]) and round(red_masked_tracks['y'][r]) == round(green_masked_tracks['y'][g]):
                intensity[g] = [red_masked_tracks['mass'][r], green_masked_tracks['mass'][g]]
                location[g] = [red_masked_tracks['x'][r], red_masked_tracks['y'][r]]
                frame[g] = red_masked_tracks['frame'][r]
                particle[g] = red_masked_tracks['particle'][r]
                break

【问题讨论】:

  • 阅读numpy.argwhere

标签: python python-3.x performance loops for-loop


【解决方案1】:

使用内部合并过滤 xyframe 匹配的行。

# example data
red = pd.DataFrame({"x": [1.2, 3.3, 5.4, 1], "y": [1.1, 10.7, 9.3, 1.1], "frame": ["a", "b", "c", "a"], "mass": [10, 20, 30, 40]})
green = pd.DataFrame({"x": [1.2, 2.3, 3.4, 1], "y": [1.1, 4.7, 6.3, 1.1], "frame": ["a", "b", "c", "a"], "mass": [50, 60, 70, 80]})

# Add rounded versions of x and y
for df in [red, green]:
    df["xr"] = df["x"].round()
    df["yr"] = df["y"].round()

matches = pd.merge(red, green, on=["xr", "yr", "frame"], suffixes=["_red", "_green"])

原则上,红色的多个匹配项可以与绿色的特定行匹配,反之亦然。如果是这样,您将不得不决定如何处理这些,例如只保留每组的第一个,使用matches = matches.groupby(["xr", "yr", "frame"]).agg("first")

您可以直接使用生成的数据帧,或将其转换为 numpy 数组:

intensity = matches[["mass_red", "mass_green"]].to_numpy()
location = matches[["x_red", "y_red"]].to_numpy()
frame = matches["frame_red"].to_numpy()
particle = matches["particle_red"].to_numpy()

【讨论】:

  • 哇,这非常有帮助。它在几秒钟内完成了我试图做的同样的事情。非常感谢您提供的有用技巧!
  • 嘿 Stuart,我想知道是否有一种方法可以将两个数据帧合并为比舍入值更大的边距。例如,我能否根据 +/- 3 值合并它们?
  • 这可能值得再问一个问题。您可以使用merge_asof 合并最接近的匹配,然后过滤掉差距过大的行。
猜你喜欢
  • 2021-08-05
  • 1970-01-01
  • 2015-04-28
  • 1970-01-01
  • 2015-11-30
  • 1970-01-01
  • 1970-01-01
  • 2022-12-14
  • 1970-01-01
相关资源
最近更新 更多