将系列索引(在模式上匹配)转换为数据框列

时间:2019-06-18 05:01:21

标签: python pandas

我有一个系列(如索引所示)显示为

E1         543
Units1_E   100
E2         553
Units2_E   420
E3         513
Units3_E   110
F1         243
Units1_F   500
F2         450
Units2_F   300
F3         400
Units3_F   200

我希望将其转换为数据帧,以便输出为

 E_F     Units
 543     100
 553     420
 513     110
 243     500
 450     300
 400     200

因此所需的输出更像是一对值列。 我不确定正则表达式是否可以有效地做到这一点,是否正在考虑使用正则表达式来过滤序列索引?

3 个答案:

答案 0 :(得分:5)

如果有必要,可以通过整数除法创建MultiIndex,并通过长度为Series的数组取模,并用Series.unstack整形,以创建Series中的配对对和不配对值:

arr = np.arange(len(s))
s.index = [arr// 2, arr % 2]
df = s.unstack()
df.columns = ['E_F','Units']
print (df)
   E_F  Units
0  543    100
1  553    420
2  513    110
3  243    500
4  450    300
5  400    200

或通过索引-配对和取消配对值创建新的DataFrame:

#pandas 0.24+
a = s.to_numpy()
#pandas below
#a = s.values
df = pd.DataFrame({'E_F':a[::2], 'Units':a[1::2]})
print (df)
   E_F  Units
0  543    100
1  553    420
2  513    110
3  243    500
4  450    300
5  400    200

另一个想法(像前2个一样慢)是测试index的第一个值是E还是F,并用GroupBy.cumcount创建SeriesMultiIndex

idx = pd.Series(np.where(s.index.str[0].isin(['E','F']), 'E_F','Units'))
s.index = [idx.groupby(idx).cumcount(), idx]
df = s.unstack()
print (df)
   E_F  Units
0  543    100
1  553    420
2  513    110
3  243    500
4  450    300
5  400    200

答案 1 :(得分:0)

使用此代码:

>>> df = pd.DataFrame({i: pd.Series(x.values.ravel()) 
                      for i, x in pd.DataFrame(s).T.groupby(lambda x: x[0] in ['E', 'F'], axis=1)})
>>> df.columns = ['E_F', 'Units']
>>> df
   E_F  Units
0  100    543
1  420    553
2  110    513
3  500    243
4  300    450
5  200    400
>>> 

答案 2 :(得分:0)

我在zips上使用s.shift来构建数据框,并在reindex上仅选择奇数行:

pd.DataFrame(list(zip(s.shift(), s)), columns=['E_F', 'Units']).reindex(index=range(1,s.size,2))

Out[225]:
      E_F  Units
1   543.0    100
3   553.0    420
5   513.0    110
7   243.0    500
9   450.0    300
11  400.0    200