【问题标题】:Managing hourly data into monthly data for the whole year Pandas将每小时数据管理为全年 Pandas 的每月数据
【发布时间】:2017-05-13 09:26:54
【问题描述】:

背景

我上传的数据links是一个监测站全年的时间序列数据。数据的格式如下所示:

我的目标

为了调查样本的时间模式,我想绘制每月样本的变化。

就像我从 plot.ly 下载的下图一样。每个方框代表原始数据的每日平均样本。线条勾勒出月平均值。

使用groupby 函数或pd.pivot 函数,我可以轻松获取某个月或某天数据的子集。

但我发现很难生成a bunch of dataframes。每一个都应该包含某个月份的每日平均数据。

通过预定义 12 个空数据帧,我可以生成 12 个数据帧来满足我的需求。 但是有没有什么巧妙的方法来划分原始数据帧,然后根据用户定义的条件生成多个数据帧。

编辑

受到@alexis 回答的启发。我试图用这些代码实现我的目标。它对我有用。

## PM is the original dataset with date, hour, and values.
position  = np.arange(1,13,1)
monthDict = {1:'Jan', 2:'Feb', 3:'Mar', 4:'Apr', 5:'May', 6:'Jun', 
            7:'Jul', 8:'Aug', 9:'Sep', 10:'Oct', 11:'Nov', 12:'Dec'}
pm['label'] = np.nan

for i in range(0,len(pm),1):
    pm['label'].iloc[i] = monthDict.get(int(pm['date'].str[4:6].iloc[i])) 

## Create an empty dataframe for containing the daily mean value.
df = pd.DataFrame(np.nan, index=np.arange(0,31,1), columns=['A'])
for i,t in enumerate(pm.label.unique()):
    df[str(t)] = np.nan
df = df.drop(['A'],1)    

mean_ = []
for i in range(0,len(pm.label.unique()),1):
    month_data = pm.groupby(['label']).get_group(pm.label.unique()[i]).groupby(pm['date'].str[6:8])['pm25'].mean()
    mean_.append(month_data.mean())
    for j in range(0,len(month_data),1):
        df[pm.label.unique()[i]].iloc[j] = month_data[j]

#### PLOT 
fig = plt.figure(figsize=(12,5))
ax = plt.subplot()
bp  = ax.boxplot( df.dropna().values, patch_artist=True, showfliers=False)
mo_me = plt.plot(position,mean_, marker = 'o', color ='k',markersize =6, label = 'Monthly Mean', lw = 1.5,zorder =3)

cs = ['#9BC4E1','k']
for box in bp['boxes']:
    box.set(color = 'b', alpha = 1)
    box.set(facecolor = cs[0], alpha = 1)
for whisker in bp['whiskers']:
    whisker.set(color=cs[1], linewidth=1,linestyle = '-')    
for cap in bp['caps']:
    cap.set(color=cs[1], linewidth=1)   
for median in bp['medians']:
    median.set(color=cs[1], linewidth=1.5)

ax.set_xticklabels(pm.label.unique(), fontsize = 14)    
# ax.set_yticklabels(ax.get_yticks(), fontsize = 12)
for label in ax.yaxis.get_ticklabels()[::2]:
    label.set_visible(False)   
for tick in ax.yaxis.get_major_ticks():
    tick.label.set_fontsize(14) 


plt.ylabel('Concentration', fontsize = 16, labelpad =14)    
plt.xlabel('Month', fontsize = 16, labelpad =14)    
plt.legend(fontsize = 14, frameon = False)
ax.set_ylim(0.0, 178)
plt.grid()
plt.show()

这是我的输出图。

任何关于我的数据管理或可视化代码的建议都将不胜感激!

【问题讨论】:

    标签: python pandas matplotlib


    【解决方案1】:

    不要生成 12 个数据帧。与其将数据拆分为多个相似的变量,不如添加一列来指示每行应属于哪个组。这是数据库表、数据框等的标准做法(有充分的理由)。

    在您的数据集上使用 groupby 按月对数据进行分组,然后在生成的 DataFrameGroupBy 对象上使用 apply() 来限制您想要的任何分析(例如,每个组的平均值。这也将使其变得容易将每月结果绘制在一起。

    您不提供任何代码,因此很难比这更具体。展示您如何按月对数据进行分组以及您想对每月数据框执行哪些操作,我将向您展示如何通过 groupby 对象将其限制为每个月。

    【讨论】:

    • 感谢您的回答。受到您的建议的启发,我尝试在这些东西上做一些工作。如果您能给我一些建议,那就太好了!
    • 很高兴你能成功。我无法仅通过浏览这么多代码提供任何具体建议,但它确实给我的印象是您可能正在使用迭代来完成pandas 可以通过其聚合和分组功能完成的事情。我真的不能说更多,但你可以把你的代码带到codereview.stackexchange.com。其目的正是为了获得有关如何改进工作代码的建议。
    • 感谢您的建议!
    猜你喜欢
    • 2022-06-27
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 2017-11-14
    • 2023-03-06
    • 2021-08-27
    • 2015-06-19
    • 1970-01-01
    相关资源
    最近更新 更多