重塑df的最佳方法是什么,以便它根据列名的相似性来堆叠列,同时在新列中保留列名的唯一ID部分?
我有一个类似于以下的df(我的实际数据还包括需要保留的NaN值):
df = pandas.DataFrame({"RX_9mm": scipy.randn(5), "RY_9mm": scipy.randn(5),"TX_9mm": scipy.randn(5), "TY_9mm": scipy.randn(5), "RX_10mm": scipy.randn(5), "RY_10mm": scipy.randn(5),"TX_10mm": scipy.randn(5), "TY_10mm": scipy.randn(5), "time": range(5)})
RX_9mm RY_9mm TX_9mm TY_9mm RX_10mm RY_10mm TX_10mm TY_10mm time
0 -0.1444 2.1319 1.9665 0.1773 0.5156 -1.8461 0.9122 1.1285 0
1 1.4831 -0.8773 -1.0112 -0.0010 1.4532 -1.3721 0.6894 -0.1781 1
2 0.3685 0.2148 -1.2216 0.0098 -1.1427 -0.1851 0.3890 0.9552 2
3 0.6843 -2.0279 -1.1342 -0.8869 0.2718 -2.4857 -1.0496 -0.4286 3
4 -1.5625 -0.2733 -0.1243 -1.2248 -0.7403 -0.5840 0.1797 -0.7014 4
但是我需要它看起来像这样:
RX RY TX TY time ID
0 -0.1444 2.1319 1.9665 0.1773 0 9mm
1 1.4831 -0.8773 -1.0112 -0.0010 1 9mm
2 0.3685 0.2148 -1.2216 0.0098 2 9mm
3 0.6843 -2.0279 -1.1342 -0.8869 3 9mm
4 -1.5625 -0.2733 -0.1243 -1.2248 4 9mm
5 0.5156 -1.8461 0.9122 1.1285 0 10mm
6 1.4532 -1.3721 0.6894 -0.1781 1 10mm
7 -1.1427 -0.1851 0.3890 0.9552 2 10mm
8 0.2718 -2.4857 -1.0496 -0.4286 3 10mm
9 -0.7403 -0.5840 0.1797 -0.7014 4 10mm
我尝试使用Chang She的“基于列标签重塑熊猫中的数据框”示例中的以下代码
但是,当我使用以下代码时:
id = df.ix[:, ['time']]
df.columns = pandas.MultiIndex.from_tuples([tuple(c.split('_')) for c in df.columns])
pandas.merge(df.stack(0).reset_index(1), id, left_index=True, right_index=True)
我得到:
RX RY TX TY RX RY TX TY time
9mm 9mm 9mm 9mm 10mm 10mm 10mm 10mm NaN
0 -0.1444 2.1319 1.9665 0.1773 0.5156 -1.8461 0.9122 1.1285 0
1 1.4831 -0.8773 -1.0112 -0.0010 1.4532 -1.3721 0.6894 -0.1781 1
2 0.3685 0.2148 -1.2216 0.0098 -1.1427 -0.1851 0.3890 0.9552 2
3 0.6843 -2.0279 -1.1342 -0.8869 0.2718 -2.4857 -1.0496 -0.4286 3
4 -1.5625 -0.2733 -0.1243 -1.2248 -0.7403 -0.5840 0.1797 -0.7014 4
我了解新列是具有测量值(RX,RY等)和ID(9mm,10mm)级别的多层,但是我不了解如何将测量值堆叠到同一列中,同时保持ID作为新列。
如果有人能解释我在做错什么来获得此输出而不是在堆积的列上,我将不胜感激。
谢谢
答案 0 :(得分:3)
您可以简化您的解决方案,不需要最后一个merge
,因为第一步中set_index
将列time
转换为index
:
df = df.set_index('time')
#expand=True in columns create MultiIndex
df.columns = df.columns.str.split('_', expand=True)
#rename_axis set MultiIndex names for names of columns after reset index
df = df.stack(dropna=False).rename_axis(['time','ID']).reset_index()
print (df)
time ID RX RY TX TY
0 0 10mm -0.549487 -0.349412 -0.620500 0.992223
1 0 9mm 0.831292 -2.465550 -0.863001 -1.335898
2 1 10mm 0.214057 -0.136649 1.831669 -0.672306
3 1 9mm -0.372416 -1.633798 -0.414518 -1.426492
4 2 10mm 0.480018 1.575599 -1.330841 -0.780036
5 2 9mm 0.352044 -1.008269 1.339841 0.423539
6 3 10mm -0.822354 0.002455 -1.099829 0.060929
7 3 9mm 1.336161 -0.066224 -1.111453 1.651180
8 4 10mm 0.627119 -0.419848 1.052179 -0.426928
9 4 9mm 0.701500 -0.833526 2.563398 0.749432
如果可以更改列的排序顺序,请使用numpy.r_
:
df = df[np.r_[df.columns[2:], df.columns[:2]]]
print (df)
RX RY TX TY time ID
0 -0.549487 -0.349412 -0.620500 0.992223 0 10mm
1 0.831292 -2.465550 -0.863001 -1.335898 0 9mm
2 0.214057 -0.136649 1.831669 -0.672306 1 10mm
3 -0.372416 -1.633798 -0.414518 -1.426492 1 9mm
4 0.480018 1.575599 -1.330841 -0.780036 2 10mm
5 0.352044 -1.008269 1.339841 0.423539 2 9mm
6 -0.822354 0.002455 -1.099829 0.060929 3 10mm
7 1.336161 -0.066224 -1.111453 1.651180 3 9mm
8 0.627119 -0.419848 1.052179 -0.426928 4 10mm
9 0.701500 -0.833526 2.563398 0.749432 4 9mm