循环存储和保存坐标数据的最快方法
Posted
技术标签:
【中文标题】循环存储和保存坐标数据的最快方法【英文标题】:Fastest way to store and save coordinate data in a loop 【发布时间】:2022-01-14 10:45:57 【问题描述】:我获得了视频中每一帧的面部特征。有477
的地标,每一个都是一个(3,)
向量。
我有一个 30 fps 的 10 分钟视频。这意味着我有18000
形状为(477,3)
的数组。我想将所有这些信息存储在一个熊猫数据框中,其中每一行都是一个框架,有 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')
我的想法是将所有内容存储在 dicts 列表中,附加到列表中,然后保存研究表明 from_dict
是创建 pandas df 的最快方法。但是,这个过程仍然很慢,因为我必须将frame_lms
保持在状态,当我将(477,3)
数组添加到其中时,它会变得很大。
解决此类问题的计算效率最高的方法是什么?
【问题讨论】:
这里有一个错字:landmark_dict[f"lm_count"] = xy
应该是 lm_count
在大括号中
您是否尝试过提前在或 pandas 数据帧中创建一个 numpy 数组,然后存储这些值?
@azelcer 追加到 numpy 数组比追加到列表更快?
我建议不要追加,而是提前创建数组:rv = np.empty((len(video, 477, 3))
,然后使用索引设置值。我认为您可能在创建对象上花费了太多时间。
不要使用熊猫。使用 numpy,存储二进制数据。您的数据是一个大矩阵。使用 dicts 或任何复杂的东西的理由为零。
【参考方案1】:
最好避免在嵌套循环的内部创建和转换为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)])
【讨论】:
谢谢。我有这个工作,但我现在如何将它保存到数据框中?当我运行pd.Dataframe(storage)
时,它会因错误而中断:ValueError: Must pass 2-d input. shape=(18000, 477, 2)
重申一下,我想要一个 18000 行 477 列的 df,每个元素都是 (2,) 数组。
我知道你想要什么。在内部循环中创建许多 numpy.ndarray
s 是昂贵的。长度为 2 的元组(而不是长度为 2 的数组)是否符合您的目的?
当然,我不明白为什么这样不行。我应该如何进行?以上是关于循环存储和保存坐标数据的最快方法的主要内容,如果未能解决你的问题,请参考以下文章