【发布时间】:2022-10-05 11:54:58
【问题描述】:
我有以下挑战:我有一个 PandasDataframe,其中包含有关唯一 ArucoID、唯一 frameID 和坐标系中相关坐标的信息。例如像这样:
# import pandas library
import pandas as pd
# lst_of_dfs = []
# dictionary with list object of values
data1 = {
\'frameID\' : [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5],
\'xPos\' : [10.0, 10.5, 11.0, 12.0, 13, 4.0, 5.0, 6.0, 7.0, 9.0, 1.5, 2.0, 2.5, 3.0, 4.0 ],
\'yPos\' : [-0.2, -0.1, -0.1, 0.0, 0.0, 0.2, 0.2, -0.1, 0.0, 0.05, -0.2, -0.1, 0.0, 0.1, 0.05],
\'ArucoID\' : [910, 910, 910, 910, 910, 898, 898, 898, 898, 898, 912, 912, 912, 912, 912],
\'Subtrial\' : [\'01\', \'01\', \'01\', \'01\', \'01\', \'01\', \'01\', \'01\', \'01\', \'01\', \'01\', \'01\', \'01\', \'01\', \'01\']
}
df1 = pd.DataFrame(data1)
data2 = {
\'frameID\' : [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5],
\'xPos\' : [9.4, 9.5, 9.0, 9.0, 10, 3.0, 4.0, 5.0, 6.0, 7.0, 2.5, 3.0, 3.5, 3.5, 5.0 ],
\'yPos\' : [-0.2, -0.1, -0.1, 0.0, 0.0, 0.2, 0.2, -0.1, 0.0, 0.05, -0.2, -0.1, 0.0, 0.1, 0.05],
\'ArucoID\' : [910, 910, 910, 910, 910, 898, 898, 898, 898, 898, 912, 912, 912, 912, 912],
\'Subtrial\' : [\'02\', \'02\', \'02\', \'02\', \'02\', \'02\', \'02\', \'02\', \'02\', \'02\', \'02\', \'02\', \'02\', \'02\', \'02\']
}
df2 = pd.DataFrame(data2)
lst_of_dfs = [df1,df2]
# creating a Dataframe object
df_TrajData = pd.concat(lst_of_dfs)
#print(df_TrajData)
现在我计算 xPos 之间的距离作为按 ArucoID 分组的 DataFrame 的滚动平均值:
#calculation of current distance of each ArucoID as rolling mean over a window of n frames (n is set as 2 frames for testing)
all_data = []
df_grouped = df_TrajData.groupby(\'ArucoID\')
for key, data in df_grouped:
#calc distance covered in window
dX = data[\'xPos\'] - data[\'xPos\'].shift(2)
#print(dX)
data[\'dX\'] = dX
all_data.append(data)
df = pd.concat(all_data)
#print(df)
现在我遇到了麻烦:我想计算速度 [s]。这将是 v = dX / (time[-1] - time[0] / framerate),其中 time[-1] 是滚动窗口的最后一个 frameID,t[0] 当前 frameID 和 framerate 是 30 帧/每/第二。
我从 (rolling_window=3, min_periods=1) 开始:
df[\'speed\'] = df.groupby(\'ArucoID\')[\'dX\'].transform(lambda x: x.rolling(3, 1).mean())
这是滚动距离的计算。我实际上想做的是这样的:
df[\'speed\'] = df.groupby(\'ArucoID\')[\'dX\'].transform(lambda s: s.rolling(3, min_periods=1).mean() / (t[-1] - t[0] /framerate))
#print(df)
任何建议,将不胜感激。提前谢谢了!
更新的问题:
我会带着一个理解问题回来,以便进一步处理。 (我不确定我是否应该提出一个新问题,或者这是否不适合在主题上更好地直接解决已解决的问题)。
我想计算 ArucoID i 和前一个 ArucoID i+1 在每个 frameID 的移动方向上的距离(前进)。然后我也想将滚动平均值应用于这个距离(rolling_headway)。
@jlandercy 提出的解决方案应该类似地工作:
1 按 frameID 对 df 进行排序。这里重要的是 ArucoID 保持未排序,因为顺序不一定是升序。换句话说,我想保持 ArucoID 的顺序。
df = df_TrajData.sort_values([\"Subtrial\", \"frameID\"])
- 确定移动的 x 位置(移动方向在 x 方向):
shifted = df.groupby([\"Subtrial\"]).shift(-1)
#print(shifted)
shifted = shifted.drop(\"frameID\", axis=1).rename(columns=lambda x: x + \"_\")
data = pd.concat([df, shifted], axis=1)
- 在点(帧)的车距计算:
def dX(x):
return np.sqrt(np.power(x[\"xPos\"] - x[\"xPos_\"], 2))
data[\'point_headway\'] = data.apply(dX, axis=1)
- 按 ArucoID 和 Subtrial 对 dfs 进行排序(因为我希望获得特定 ArucoID 的滚动平均值),然后应用滚动平均值(假设此处的窗口大小为 3)。
data[\"rolling_headway\"] = data.sort_values([\"Subtrial\", \"ArucoID\",\'frameID\']).groupby([\"Subtrial\", \"ArucoID\"]).rolling(3, min_periods=2).mean()[\"point_headway\"].values
#print(data)
结果是:
frameID xPos yPos ... ArucoID_ point_headway rolling_headway
5 1 4.0 0.20 ... 912.0 2.5 2.750000
6 2 5.0 0.20 ... 912.0 3.0 4.166667
7 3 6.0 -0.10 ... 912.0 3.5 5.500000
8 4 7.0 0.00 ... 912.0 4.0 NaN
9 5 9.0 0.05 ... 912.0 5.0 9.500000
我的预期(见最后一栏)
frameID xPos yPos ... ArucoID_ point_headway expected
5 1 4.0 0.20 ... 912.0 2.5 NaN
6 2 5.0 0.20 ... 912.0 3.0 NaN
7 3 6.0 -0.10 ... 912.0 3.5 3.000000 (2.5+3.0+3.5)/3
8 4 7.0 0.00 ... 912.0 4.0 3.500000 (3.0+3.5+4.0)/3
9 5 9.0 0.05 ... 912.0 5.0 4.166667 (3.5+4.0+5.0)/3
我的思维错误在哪里?我想我排序错了,不是吗?
提前感谢您的建议!