【问题标题】:Pandas Comparing hourly multiple year data in one plot熊猫在一个图中比较每小时的多年数据
【发布时间】:2018-10-15 21:27:04
【问题描述】:

所以我在这个表单上有一个名为 year 的 pandas 数据框:

                           discharge (m^3/s)  
date                                                                   
2016-01-01 00:00:00           17.6930
2016-01-01 01:00:00           17.3247
2016-01-01 02:00:00           17.2436
2016-01-01 03:00:00           17.5696
2016-01-01 04:00:00           16.4074
2016-01-01 05:00:00           17.5696
2016-01-01 06:00:00           17.0420            
....
2017-12-31 20:00:00           10.5911           
2017-12-31 21:00:00           10.5620          
2017-12-31 22:00:00           10.7374          
2017-12-31 23:00:00           10.5620 

数据集包含几年的放电数据,我想做一个比较 f.ex 的图。 2016 年和 2017 年的一月。

到目前为止,我的尝试一直是提取所需的月份,并将它们相互叠加。但这不起作用,正如您在这张图片中看到的那样:

Attempt plot 1

我的代码是:

# Comparison full months
def plotmonthdischarge(month, years, number_of_years):
    df = pd.read_csv('resources\FinVannføringEidsfjordvatn.csv', encoding = 'ISO-8859-1',sep=';')
    df['date'] = pd.to_datetime(df['date'],dayfirst=True)
    df = df.set_index(df['date'])
    df['Day Of Year'] = df['date'].dt.dayofyear
    df = df.drop(['date'], axis = 1)
    df = df.replace(to_replace='-9999', value = np.NaN)


    fig, ax = plt.subplots()

    # For a starting year 2016 and a 1 following year
    # Call example:
    # plotmonthdischarge(1,[2016],2)
    if len(years) == 1:
        start_year = years[0]
        for i in range(number_of_years):
            year = df['{0}-{1}-01 00:00:00'.format(start_year+i,month):'{0}-{1}-31 23:59:59'.format(start_year+i,month)]
            ax.plot(year['discharge (m^3/s)'], label = 'Year {}'.format(start_year+i))

    # Just for plotting(ignore)
    formatted_list = ['{:>3}' for i in range(number_of_years)] 
    string_of_years = ', '.join(formatted_list).format(*[start_year+i for i in range(number_of_years)])
    plt.title('Comparison plot of years {}'.format(string_of_years))

    # Specific years  2006 and 2017
    # Call example:
    # plotmonthdischarge(1,[2006,2017],1)
    if len(years) > 1:
        number_of_years = 1
        for item in years:
            year = df['{0}-{1}-01 00:00:00'.format(item,month):'{0}-{1}-31 23:59:59'.format(item,month)]
            ax.plot(year['Day Of Year'],year['discharge (m^3/s)'], label = 'Year {}'.format(item))

    # Just for plotting(ignore)
    formatted_list = ['{:>3}' for item in years] 
    string_of_years = ', '.join(formatted_list).format(*years)
    plt.title('Comparison plot of years {}'.format(string_of_years))
    print(year)

    plt.suptitle(r'Discharge $m^{3}s^{-1}$')
    plt.ylabel(r'Discharge $m^{3}s^{-1}$')
    plt.legend()
    plt.grid(True)

plotmonthdischarge(1,[2015,2016],1)

我的下一个尝试是我在其他帖子中找到的东西

df['Day Of Year'] = df['date'].dt.dayofyear

然后绘制一个月中的所有日子:

 ax.plot(year['Day Of Year'],year['discharge (m^3/s)'], label = 'Year {}'.format(item))

这工作正常,但似乎每天只记录一个左右的点,这很糟糕,因为我正在处理每小时数据。

Attempt plot 2

还尝试从日期时间(我的索引)中删除年份,并在只有月、日和小时的日期时间索引上绘图,但没有真正成功。

编辑

单年(2015 年 1 月)图的示例图。

Correct plot I get of only one year

【问题讨论】:

    标签: python pandas datetime


    【解决方案1】:

    如果您的数据没有缺失值 (NaN),我建议使用 .loc 从 DataFrame 中切出所需的年份,并使用 .values 绘制底层 numpy 数组:

    fig, ax = plt.subplots()
    for yr in ['2016', '2017']:
        ax.plot(df.loc[yr].values, label = 'Year {}'.format(yr))
    

    一种更灵活的方法是手动计算一年中的小时,而不是一年中的哪一天,然后从那里开始:

    df['hourofyear'] = 24 * (df.index.dayofyear - 1) + df.index.hour
    fig, ax = plt.subplots()
    for yr, g in df.groupby(df.index.year):
        g.plot('hourofyear', 'discharge (m^3/s)', label='Year {}'.format(yr), ax=ax)
    

    【讨论】:

    • 我实现了第一种方法,它似乎正在工作。这个特定的数据集不包含 NaN,但我希望它与包含 NaN 的数据集一起使用。使用 NaN 时,您的一种解决方案是否比另一种更有效?
    • @JohanR,是的,我会采用第二种方法。
    猜你喜欢
    • 1970-01-01
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多