我熟悉标准的Pandas枢轴功能,但是我要做的是有所不同-我不习惯使用pivot
。
设置代码:
import pandas as pd
import io
csvA = io.StringIO(u'''
month chicken_a chicken_b chicken_c turkey_a turkey_b turkey_c
1 10 20 30 1 2 3
2 11 22 33 101 202 303
''')
dfA = pd.read_csv(csvA, sep = '\t')
哪种产量:
month chicken_a chicken_b chicken_c turkey_a turkey_b turkey_c
0 1 10 20 30 1 2 3
1 2 11 22 33 101 202 303
我想将'_a', '_b', and '_c'
部分转到月份,但保留“鸡肉”和“火鸡”标题。最终结果将如下所示:
month chicken turkey
0 1a 10 1
1 1b 20 2
2 1c 30 3
3 2a 11 101
4 2b 22 202
5 2c 33 303
'_a', '_b', '_c'
部分将一如既往,并且会提前知道。
我可以通过for
循环来破解它,但是我想知道是否还有更疯狂的方法。
答案 0 :(得分:1)
我找到了一个我不喜欢的解决方案,但仍然觉得有些笨拙,但是没有循环,可以完成工作。我绝对愿意寻求更好的解决方案:
df = dfA.set_index('month').stack().reset_index()
df['month_type'] = df['month'].astype(str) + df['level_1'].str[-1:]
df['level_1'] = df['level_1'].str[:-2]
df = df.drop(['month'], axis = 1)
df = df.pivot(index = 'month_type', columns = 'level_1', values = 0)
df = pd.DataFrame(df.to_records())
答案 1 :(得分:1)
在set_index
列月份之后,您可以通过用MultiIndex
拆分列名称来将列更改为'_'
。使用stack
之后,只需要将join
的{{1}}简化为MultiIndex
,然后再加上Index
:
reset_index
您会得到
#first convert month column to str, for later join
dfA['month'] = dfA['month'].astype(str)
#set month as index
dfA = dfA.set_index('month')
#change the column to MultiIndex using split
dfA.columns = pd.MultiIndex.from_tuples([col.split('_') for col in dfA.columns])
# stack
dfA = dfA.stack()
# simple index from the MultiIndex
dfA.index = pd.Index([''.join(ind) for ind in dfA.index], name='month')
#reset index
dfA = dfA.reset_index()
答案 2 :(得分:0)
pd.wide_to_long
在这种情况下效果很好:
dfB = pd.wide_to_long(dfA,['chicken','turkey'],i='month',j='suf',suffix='_\w')
结果
chicken turkey
month suf
1 _a 10 1
2 _a 11 101
1 _b 20 2
2 _b 22 202
1 _c 30 3
2 _c 33 303
然后您可以将两个索引连接成一个 month
列
dfB.reset_index(inplace = True)
dfB['month'] = dfB.astype({'month':'str'}).month + dfB.suf.str[1]
dfB.drop(columns='suf', inplace = True)
输出符合要求
month chicken turkey
0 1a 10 1
1 2a 11 101
2 1b 20 2
3 2b 22 202
4 1c 30 3
5 2c 33 303