DataFrames/Indexes 嵌套在 python pandas 中
Nested DataFrames/Indexes in python pandas
瞄准
我正在尝试使用 python pandas 处理来自一些视频跟踪实验的数据。我在一个结构上放置了一些点标记,并随时间跟踪这些点的 XY 坐标。这些数据一起描述了测试过程中结构的形状。我无法将我的数据安排到 hierarchical/nested DataFrame
对象中。
正在导入数据
我的跟踪方法输出每个视频帧的每个点的 X、Y 坐标(和时间)。此数据存储在 csv
个文件中,每个变量一列,每个视频帧一行:
t,x,y
0.000000000E0,-4.866015168E2,-2.116143012E0
1.000000000E-1,-4.866045511E2,-2.123012558E0
2.000000000E-1,-4.866092436E2,-2.129722560E0
使用 pandas.read_csv
我能够将这些 csv
文件读入 DataFrame
s,具有相同的 columns/rows 格式:
In [1]: pd.read_csv(point_a.csv)
Out[17]:
t x y
0 0.0 -486.601517 -2.116143
1 0.1 -486.604551 -2.123013
2 0.2 -486.609244 -2.129723
目前没问题。
创建层次结构
我想合并上面的几个 DataFrame
(每个点一个),并创建一个带有分层列的大型 DataFrame
,其中所有变量共享一个索引(视频帧) .请参阅下面的列 point_a
、point_b
等,以及 x
、y
、t
的子列。 shape
列表示用于绘制结构形状的有用向量。
| point_a | point_b | point_c | shape
frames | x y t | x y t | x y t | x y
-----------------------------------------------------------------------------------
0 | xa0 ya0 ta0 | xb0 yb0 tb0 | xc0 yc0 tc0 | [xa0,xb0,xc0] [ya0,yb0,yc0]
1 | xa1 ya1 ta1 | xb1 yb1 tb1 | xc1 yc1 tc1 | [xa1,xb1,xc1] [ya1,yb1,yc1]
2 | xa2 ya2 ta2 | xb2 yb2 tb2 | xc2 yc2 tc2 | [xa2,xb2,xc2] [ya2,yb2,yc2]
3 | xa3 ya3 ta3 | xb3 yb3 tb3 | xc3 yc3 tc3 | [xa3,xb3,xc3] [ya3,yb3,yc3]
我想指定一个视频帧,并能够获取该帧的变量值,例如df[1].point_b.y = yb1
到目前为止我尝试了什么
嵌套 dict
s 作为输入
我以前处理这种事情的方法是使用嵌套的dict
s:
nested_dicts = {
"point_a": {
"x": [xa0, xa1, xa2],
"y": [ya0, ya1, ya2],
"t": [ta0, ta1, ta2],
},
"point_b": {
"x": [xb0, xb1, xb2],
"y": [yb0, yb1, yb2],
"t": [tb0, tb1, tb2],
},
"point_c": {
"x": [xc0, xc1, xc2],
"y": [yc0, yc1, yc2],
"t": [tc0, tc1, tc2],
},
}
这完成了我需要的一切 除了 按帧编号分割数据。当我尝试使用此嵌套 dict
作为 DataFrame
的输入时,我得到以下信息:
In [1]: pd.DataFrame(nested_dicts)
Out[2]:
point_a point_b point_c
t [ta0, ta1, ta2] [tb0, tb1, tb2] [tc0, tc1, tc2]
x [xa0, xa1, xa2] [xb0, xb1, xb2] [xc0, xc1, xc2]
y [ya0, ya1, ya2] [yb0, yb1, yb2] [yc0, yc1, yc2]
问题:没有共享帧索引。 DataFrame
以t
、x
、y
为索引。
为嵌套字典输入指定索引
如果我尝试指定索引:
In [1]: pd.DataFrame(nested_dicts, index=range(number_of_frames))
然后我得到一个 DataFrame
,行数正确,但没有子列,并且充满了 NaN
:
Out[2]:
point_a point_b point_c
0 NaN NaN NaN
1 NaN NaN NaN
2 NaN NaN NaN
3 NaN NaN NaN
4 NaN NaN NaN
5 NaN NaN NaN
6 NaN NaN NaN
7 NaN NaN NaN
8 NaN NaN NaN
分别添加每个 DataFrame
如果我为每个点创建一个 DataFrame
:
point_a = point_b =
t x y t x y
0 ta0 xa0 ya0 0 tb0 xb0 yb0
1 ta1 xa1 ya1 1 tb1 xb1 yb1
2 ta2 xa2 ya2 2 tb2 xb2 yb2
并将这些传递给一个DataFrame
,表示要共享的索引,如下:
In [1]: pd.DataFrame({"point_a":point_a,"point_b":point_b},index=point_a.index)
然后我得到以下内容,其中仅包含 x
、y
、t
作为字符串:
Out[2]:
point_a point_b
0 (t,) (t,)
1 (x,) (x,)
2 (y,) (y,)
我想你可以使用 dict comprehension
和 concat
and then reshape DataFrame
by stack
and unstack
:
df = pd.concat({key:pd.DataFrame(nested_dicts[key]) for key in nested_dicts.keys()})
.stack()
.unstack([0,2])
print (df)
point_a point_b point_c
t x y t x y t x y
0 ta0 xa0 ya0 tb0 xb0 yb0 tc0 xc0 yc0
1 ta1 xa1 ya1 tb1 xb1 yb1 tc1 xc1 yc1
2 ta2 xa2 ya2 tb2 xb2 yb2 tc2 xc2 yc2
另一个 swaplevel
and sort first level in MultiIndex
in columns by sort_index
的解决方案:
df = pd.concat({key:pd.DataFrame(nested_dicts[key]) for key in nested_dicts.keys()})
.unstack(0)
df.columns = df.columns.swaplevel(0,1)
df = df.sort_index(level=0, axis=1)
print (df)
point_a point_b point_c
t x y t x y t x y
0 ta0 xa0 ya0 tb0 xb0 yb0 tc0 xc0 yc0
1 ta1 xa1 ya1 tb1 xb1 yb1 tc1 xc1 yc1
2 ta2 xa2 ya2 tb2 xb2 yb2 tc2 xc2 yc2
或者您可以使用 Panel
with transpose
and to_frame
:
df = pd.Panel(nested_dicts).transpose(0,1,2).to_frame().unstack()
print (df)
point_a point_b point_c
minor t x y t x y t x y
major
0 ta0 xa0 ya0 tb0 xb0 yb0 tc0 xc0 yc0
1 ta1 xa1 ya1 tb1 xb1 yb1 tc1 xc1 yc1
2 ta2 xa2 ya2 tb2 xb2 yb2 tc2 xc2 yc2
瞄准
我正在尝试使用 python pandas 处理来自一些视频跟踪实验的数据。我在一个结构上放置了一些点标记,并随时间跟踪这些点的 XY 坐标。这些数据一起描述了测试过程中结构的形状。我无法将我的数据安排到 hierarchical/nested DataFrame
对象中。
正在导入数据
我的跟踪方法输出每个视频帧的每个点的 X、Y 坐标(和时间)。此数据存储在 csv
个文件中,每个变量一列,每个视频帧一行:
t,x,y
0.000000000E0,-4.866015168E2,-2.116143012E0
1.000000000E-1,-4.866045511E2,-2.123012558E0
2.000000000E-1,-4.866092436E2,-2.129722560E0
使用 pandas.read_csv
我能够将这些 csv
文件读入 DataFrame
s,具有相同的 columns/rows 格式:
In [1]: pd.read_csv(point_a.csv)
Out[17]:
t x y
0 0.0 -486.601517 -2.116143
1 0.1 -486.604551 -2.123013
2 0.2 -486.609244 -2.129723
目前没问题。
创建层次结构
我想合并上面的几个 DataFrame
(每个点一个),并创建一个带有分层列的大型 DataFrame
,其中所有变量共享一个索引(视频帧) .请参阅下面的列 point_a
、point_b
等,以及 x
、y
、t
的子列。 shape
列表示用于绘制结构形状的有用向量。
| point_a | point_b | point_c | shape
frames | x y t | x y t | x y t | x y
-----------------------------------------------------------------------------------
0 | xa0 ya0 ta0 | xb0 yb0 tb0 | xc0 yc0 tc0 | [xa0,xb0,xc0] [ya0,yb0,yc0]
1 | xa1 ya1 ta1 | xb1 yb1 tb1 | xc1 yc1 tc1 | [xa1,xb1,xc1] [ya1,yb1,yc1]
2 | xa2 ya2 ta2 | xb2 yb2 tb2 | xc2 yc2 tc2 | [xa2,xb2,xc2] [ya2,yb2,yc2]
3 | xa3 ya3 ta3 | xb3 yb3 tb3 | xc3 yc3 tc3 | [xa3,xb3,xc3] [ya3,yb3,yc3]
我想指定一个视频帧,并能够获取该帧的变量值,例如df[1].point_b.y = yb1
到目前为止我尝试了什么
嵌套 dict
s 作为输入
我以前处理这种事情的方法是使用嵌套的dict
s:
nested_dicts = {
"point_a": {
"x": [xa0, xa1, xa2],
"y": [ya0, ya1, ya2],
"t": [ta0, ta1, ta2],
},
"point_b": {
"x": [xb0, xb1, xb2],
"y": [yb0, yb1, yb2],
"t": [tb0, tb1, tb2],
},
"point_c": {
"x": [xc0, xc1, xc2],
"y": [yc0, yc1, yc2],
"t": [tc0, tc1, tc2],
},
}
这完成了我需要的一切 除了 按帧编号分割数据。当我尝试使用此嵌套 dict
作为 DataFrame
的输入时,我得到以下信息:
In [1]: pd.DataFrame(nested_dicts)
Out[2]:
point_a point_b point_c
t [ta0, ta1, ta2] [tb0, tb1, tb2] [tc0, tc1, tc2]
x [xa0, xa1, xa2] [xb0, xb1, xb2] [xc0, xc1, xc2]
y [ya0, ya1, ya2] [yb0, yb1, yb2] [yc0, yc1, yc2]
问题:没有共享帧索引。 DataFrame
以t
、x
、y
为索引。
为嵌套字典输入指定索引
如果我尝试指定索引:
In [1]: pd.DataFrame(nested_dicts, index=range(number_of_frames))
然后我得到一个 DataFrame
,行数正确,但没有子列,并且充满了 NaN
:
Out[2]:
point_a point_b point_c
0 NaN NaN NaN
1 NaN NaN NaN
2 NaN NaN NaN
3 NaN NaN NaN
4 NaN NaN NaN
5 NaN NaN NaN
6 NaN NaN NaN
7 NaN NaN NaN
8 NaN NaN NaN
分别添加每个 DataFrame
如果我为每个点创建一个 DataFrame
:
point_a = point_b =
t x y t x y
0 ta0 xa0 ya0 0 tb0 xb0 yb0
1 ta1 xa1 ya1 1 tb1 xb1 yb1
2 ta2 xa2 ya2 2 tb2 xb2 yb2
并将这些传递给一个DataFrame
,表示要共享的索引,如下:
In [1]: pd.DataFrame({"point_a":point_a,"point_b":point_b},index=point_a.index)
然后我得到以下内容,其中仅包含 x
、y
、t
作为字符串:
Out[2]:
point_a point_b
0 (t,) (t,)
1 (x,) (x,)
2 (y,) (y,)
我想你可以使用 dict comprehension
和 concat
and then reshape DataFrame
by stack
and unstack
:
df = pd.concat({key:pd.DataFrame(nested_dicts[key]) for key in nested_dicts.keys()})
.stack()
.unstack([0,2])
print (df)
point_a point_b point_c
t x y t x y t x y
0 ta0 xa0 ya0 tb0 xb0 yb0 tc0 xc0 yc0
1 ta1 xa1 ya1 tb1 xb1 yb1 tc1 xc1 yc1
2 ta2 xa2 ya2 tb2 xb2 yb2 tc2 xc2 yc2
另一个 swaplevel
and sort first level in MultiIndex
in columns by sort_index
的解决方案:
df = pd.concat({key:pd.DataFrame(nested_dicts[key]) for key in nested_dicts.keys()})
.unstack(0)
df.columns = df.columns.swaplevel(0,1)
df = df.sort_index(level=0, axis=1)
print (df)
point_a point_b point_c
t x y t x y t x y
0 ta0 xa0 ya0 tb0 xb0 yb0 tc0 xc0 yc0
1 ta1 xa1 ya1 tb1 xb1 yb1 tc1 xc1 yc1
2 ta2 xa2 ya2 tb2 xb2 yb2 tc2 xc2 yc2
或者您可以使用 Panel
with transpose
and to_frame
:
df = pd.Panel(nested_dicts).transpose(0,1,2).to_frame().unstack()
print (df)
point_a point_b point_c
minor t x y t x y t x y
major
0 ta0 xa0 ya0 tb0 xb0 yb0 tc0 xc0 yc0
1 ta1 xa1 ya1 tb1 xb1 yb1 tc1 xc1 yc1
2 ta2 xa2 ya2 tb2 xb2 yb2 tc2 xc2 yc2