问题描述
'Daily Mean Temp for place name 2015' # One table title per year
'Day' 'JAN' 'FEB' 'MAR' ... 'DEC'
1 23 26 21 ... 14
2 20 30 22 ... 12
3 26 27 22 ... 16
... ... ... ... ... ...
31 28 - 19 ... 11
我想把它变成这种格式:
'date' 'mean_temp'
2015-01-01 23
2015-01-02 20
2015-01-03 26
我一直无法找到解决方案,希望有任何想法吗?
解决方法
首先映射您的月份,然后取消旋转您的 df
import padas as pd
df.columns = [col.title() for col in df.columns]
df_unpivot = df.melt(id_vars=["Day"],var_name="month",value_name="mean_temp")
然后添加带有日期的新列(如果日期不存在,则为 naT)
df_unpivot['date'] = pd.to_datetime(df_unpivot["Day"].map(str) + "-" + df_unpivot["month"] + "-2015",format='%d-%b-%Y',errors="coerce")
删除不需要的列和无效日期
df_unpivot.drop(["Day","month"],axis=1,inplace=True)
df_unpivot.dropna(inplace=True)
将日期设置为索引
df_unpivot.set_index("date",inplace=True)
,
在一行中:
pd.concat([
pd.concat((pd.Series(pd.date_range(start=f'{y}/{m}',end=pd.Timestamp(f'{y}/{m}') + pd.offsets.MonthEnd(0),freq='D'),name='Day'),df[c].rename('mean_temp')[:pd.Period(f'{y}/{m}').days_in_month]),axis=1)
for y,df in sorted(temp_dfs.items())
for m,c in enumerate(['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC'],start=1)
],axis=0)
结果如下:
Day mean_temp
0 2015-01-01 16
1 2015-01-02 29
2 2015-01-03 33
3 2015-01-04 28
4 2015-01-05 17
.. ... ...
26 2019-12-27 32
27 2019-12-28 39
28 2019-12-29 -2
29 2019-12-30 39
30 2019-12-31 1
前面的代码假设 temp_dfs
是一个 dict
,其中所有的 DataFrame
都是按年份组织的:键是所有可用的年份。我使用此代码生成示例 dict
:
import pandas as pd
import numpy as np
temp_dfs = {
y: pd.DataFrame(
data=np.column_stack((np.arange(1,32),np.random.randint(-3,40,(31,12)))),columns=['Day','JAN','DEC']
) for y in range(2015,2020)
}