在循环中存储和保存坐标数据的最快方法

Fastest way to store and save coordinate data in a loop

我获取视频中每一帧的人脸特征点。有 477 个地标,每个都是一个 (3,) 向量。

我有一个 30 帧/秒的 10 分钟视频。这意味着我有 18000 个形状为 (477,3) 的数组。我想将所有这些信息存储在一个 pandas 数据框中,其中每一行都是一个框架并且有 477 列,每个 (3,) 数组一列。

目前,我正在这样做:

frame_lms = []
for frame in video:
    landmark_dict = {}
    lm_count = 0
    for landmark in frame:
        x = landmark.x
        y = landmark.y
        xy = np.array([x,y])
        landmark_dict[f"lm_{count}"] = xy
        lm_count+=1
    frame_lms.append(landmark_dict)
df = pd.DataFrame.from_dict(frame_lms)
df.to_csv('save.csv')

我想到了将所有内容存储在字典列表中,附加到列表中,然后从研究中保存,表明 from_dict 是创建 pandas df 的最快方法。但是,这个过程仍然很慢,因为我必须保持 frame_lms 状态,当我将 (477,3) 数组附加到其中时,它会变得很大。

解决此类问题的计算效率最高的方法是什么?

最好避免在嵌套循环的内部创建和转换为 numpy.array 多个对象。如果将内部循环中的 xy = np.array([x, y]) 更改为 xy = (x, y),您的代码会快得多。在下面的代码中,我保留了到 numpy.ndarray 的转换,因为我知道这对 OP 来说是可以的。

由于 python 管理列表非常有效,您可以使用数据创建列表列表,并在创建 DataFrame 时指定列名。

更快,pythonic创建列表的方式是

rv = [[(lm.x, lm.y) for lm in f] for f in video]

相当于下面的代码,稍微慢一点(不推荐):

import numpy as np

# load video here

rv = []
for frame in video:
    internal = []
    for landmark in frame:
        internal.append((landmark.x, landmark.y))
    rv.append(internal)

您可以使用

从列表中创建 DataFrame
df = pd.DataFrame(rv, columns=[f"lm_{count}" for count in range(477)])