我有一个系列(如索引所示)显示为
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
因此所需的输出更像是一对值列。 我不确定正则表达式是否可以有效地做到这一点,是否正在考虑使用正则表达式来过滤序列索引?
答案 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
创建Series
和MultiIndex
:
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)
我在zip
和s
上使用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