pan*_*ump 1 python pivot reshape dataframe pandas
我有以下格式的数据框:
df = pd.DataFrame({'Date': np.repeat(['20190101', '20190102'], 8),
'Category': list(np.repeat(['A', 'B'], 4))*2,
'Sub-Category': list(np.repeat(['X', 'Y'], 2))*4,
'Samples': range(16)})
# print(df)
Date Category Sub-Category Samples
0 20190101 A X 0
1 20190101 A X 1
2 20190101 A Y 2
3 20190101 A Y 3
4 20190101 B X 4
5 20190101 B X 5
6 20190101 B Y 6
7 20190101 B Y 7
8 20190102 A X 8
9 20190102 A X 9
10 20190102 A Y 10
11 20190102 A Y 11
12 20190102 B X 12
13 20190102 B X 13
14 20190102 B Y 14
15 20190102 B Y 15
Run Code Online (Sandbox Code Playgroud)
每个日期内都有一个类别,每个类别内又有多个子类别。此外,每个子类别都有多个样本。
我想要做的是将“子类别”列从长格式转换为宽格式,而不对样本进行任何聚合,如下所示:
desired_df = pd.DataFrame({'Date': np.repeat(['20190101', '20190102'], 4),
'Category': list(np.repeat(['A', 'B'], 2))*2,
'X': [0, 1, 4, 5, 8, 9, 12, 13],
'Y': [2, 3, 6, 7, 10, 11, 14, 15]
})
# print(desired_df)
Date Category X Y
0 20190101 A 0 2
1 20190101 A 1 3
2 20190101 B 4 6
3 20190101 B 5 7
4 20190102 A 8 10
5 20190102 A 9 11
6 20190102 B 12 14
7 20190102 B 13 15
Run Code Online (Sandbox Code Playgroud)
我想我已经找到了实现这一目标的方法,但感觉相当丑陋和老套:它涉及首先为样本编号创建一个新列,然后创建一个新索引,将所有这些信息组合在一起,旋转,然后分离一切再次发生:
def add_sample_index(df):
df['sample_index'] = range(len(df))
return df
new_df = df.groupby(['Date', 'Category', 'Sub-Category']).apply(add_sample_index)
new_df['new_index'] = new_df['Date'] + '_' + new_df['Category'] + '_' + new_df['sample_index'].astype(str)
wide_df = new_df.pivot(index='new_index', columns='Sub-Category', values='Samples').reset_index()
wide_df['Date'], wide_df['Category'], wide_df['sample_index'] = wide_df['new_index'].str.split('_').str
wide_df.drop(['new_index', 'sample_index'],
inplace=True, axis='columns')
final_df = wide_df[['Date', 'Category', 'X', 'Y']]
# print((final_df == desired_df).all().all())
True
Run Code Online (Sandbox Code Playgroud)
我的问题:有没有更好、更有效的方法来解决这个问题?
首先我们使用groupby cumcount创建附加密钥,那么它更像是pivot问题
df['New']=df.groupby(['Date','Category','Sub-Category']).cumcount()
yourdf=df.pivot_table(values='Samples',index=['Date','Category','New'],columns='Sub-Category').reset_index()
yourdf
Out[703]:
Sub-Category Date Category New X Y
0 20190101 A 0 0 2
1 20190101 A 1 1 3
2 20190101 B 0 4 6
3 20190101 B 1 5 7
4 20190102 A 0 8 10
5 20190102 A 1 9 11
6 20190102 B 0 12 14
7 20190102 B 1 13 15
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
887 次 |
| 最近记录: |