我有一个大的数据框架,我需要pivot to long。数据帧的格式为:
np.random.seed(0)
df = pd.DataFrame({'2010_A(weekly)': np.random.rand(3),
'2011_A(weekly)': np.random.rand(3),
'2010_B(weekly)': np.random.rand(3),
'2011_B(weekly)': np.random.rand(3),
'X' : np.random.randint(3, size=3)})
df['id'] = df.index
df
如果名字相反,像这样:
np.random.seed(0)
df = pd.DataFrame({'A(weekly)_2010': np.random.rand(3),
'A(weekly)_2011': np.random.rand(3),
'B(weekly)_2010': np.random.rand(3),
'B(weekly)_2011': np.random.rand(3),
'X' : np.random.randint(3, size=3)})
df['id'] = df.index
df
很容易使用wide_to_long
将我的表转换成所需的格式,如下所示:
pd.wide_to_long(df, ['A(weekly)', 'B(weekly)'], i='id',
j='year', sep='_')
然而,我还没有找到一种方法使widde_to_long考虑反向名称。
是否有使用wide_to_long
的方式,它使用列的结尾来识别stubname?
期望的输出是一个5列长的数据框,列名为"id", "year", "X", "A(weekly)", "B(weekly)"
这是不可能的pd.wide_to_long
。您必须使用其他方法或重命名列来交换字段:
>>> pd.wide_to_long(df.rename(columns=lambda x: '_'.join(x.split('_')[::-1])),
['A(weekly)', 'B(weekly)'], i='id', j='year', sep='_')
X A(weekly) B(weekly)
id year
0 2010 0 0.548814 0.437587
1 2010 1 0.715189 0.891773
2 2010 1 0.602763 0.963663
0 2011 0 0.544883 0.383442
1 2011 1 0.423655 0.791725
2 2011 1 0.645894 0.528895
一个选项是pyjnanitor中的pivot_longer -对于这个特殊的用例,使用.value
占位符来表示存根(您希望保留作为标题的列),并使用names_sep
基于分隔符分割列:
# pip insall pyjanitor
import pandas as pd
import janitor
df.pivot_longer(index = ['X', 'id'], names_to = ('year', '.value'), names_sep = '_')
X id year A(weekly) B(weekly)
0 0 0 2010 0.548814 0.437587
1 1 1 2010 0.715189 0.891773
2 1 2 2010 0.602763 0.963663
3 0 0 2011 0.544883 0.383442
4 1 1 2011 0.423655 0.791725
5 1 2 2011 0.645894 0.528895