我有一个如下所示的 pandas 数据框:
id val date period1 period2 period3
1 4 05/03 1 2 3
2 6 06/03 4 5 6
3 2 07/03 7 8 9
4 9 08/03 5 7 1
我想根据日期和时间段将其从宽格式转换为长格式,如下所示:
id val date period data
1 4 05/03 06/03 1
07/03 2
08/03 3
2 6 06/03 07/03 4
08/03 5
09/03 6
3 2 07/03 08/03 7
09/03 8
10/03 9
4 9 08/03 09/03 5
10/03 7
11/03 1
即 period 的值将是 date+1month 的值(年份也可能改变)等等,其对应的值出现在 data 列中,而 dataframe 的其余部分保持不变。
我怎样才能实现这个目标?
最佳答案
首先通过 DataFrame.set_index
reshape 值与 DataFrame.stack
.
然后将 date
列转换为日期时间和月份周期 Series.dt.to_period
,为每组添加计数器 GroupBy.cumcount
并通过 Series.dt.strftime
更改格式:
df = (df.set_index(['id','val','date'])
.rename_axis('period', axis=1)
.stack()
.reset_index(name='data'))
s = pd.to_datetime(df['date'], format='%m/%y').dt.to_period('m')
df['period'] = df.groupby(['id','val','date']).cumcount().add(s + 1).dt.strftime('%m/%y')
print (df)
id val date period data
0 1 4 05/03 06/03 1
1 1 4 05/03 07/03 2
2 1 4 05/03 08/03 3
3 2 6 06/03 07/03 4
4 2 6 06/03 08/03 5
5 2 6 06/03 09/03 6
6 3 2 07/03 08/03 7
7 3 2 07/03 09/03 8
8 3 2 07/03 10/03 9
9 4 9 08/03 09/03 5
10 4 9 08/03 10/03 7
11 4 9 08/03 11/03 1
最后,如果需要前 3 列为空值 - 是否可以通过 DataFrame.duplicated
,但得到混合值 - 带有字符串的数字,因此数字函数应该失败:
df.loc[df.duplicated(['id','val','date']), ['id','val','date']] = ''
print (df)
id val date period data
0 1 4 05/03 06/03 1
1 07/03 2
2 08/03 3
3 2 6 06/03 07/03 4
4 08/03 5
5 09/03 6
6 3 2 07/03 08/03 7
7 09/03 8
8 10/03 9
9 4 9 08/03 09/03 5
10 10/03 7
11 11/03 1
关于python-3.x - 根据日期列从宽到长的 Pandas ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57568635/