使用Python将日历年到水年的数据帧重新排序

时间:2018-08-30 21:48:11

标签: python-3.x pandas time-series pandas-groupby

这个问题已经用R解决了,但是我还没有看到关于Python的有用示例。我想学习如何将日历年(1990年1月1日到2010年12月31日)的排放数据转换为水年数据(即从1990年1月1日到2010年9月31日)。谢谢您的协助。

2 个答案:

答案 0 :(得分:0)

您可以使用apply并编写自己的函数来创建新列WY

如果您有df

                 Date  Discharge
0 2011-10-01 00:00:00  0.0
1 2011-10-01 01:00:00  0.0
2 2011-10-01 02:00:00  0.0
3 2011-10-01 03:00:00  0.0
4 2011-10-01 04:00:00  0.0

然后:

import pandas as pd

def assign_wy(row):
    if row.Date.month>=10:
        return(pd.datetime(row.Date.year+1,1,1).year)
    else:
        return(pd.datetime(row.Date.year,1,1).year)

df['WY'] = df.apply(lambda x: assign_wy(x), axis=1)

答案 1 :(得分:0)

  • 使用来自USGS 03335500 WABASH RIVER AT LAFAYETTE, IN的数据

    • 日期:2001-10-01-2017-09-31
  • 必须在 for element in coordonnees_voisine: element_voisin = self.obtenir_case(element[0], element[1]) if element_voisin == case: case.ajouter_une_mine_voisine() else: None 列中将'datetime' datetime设置为dtype,或在导入数据后使用parse_dates将其设置为pd.to_datetime()

  • 使用pandas.Series.where确定水年。

    • 使用.dt accessor提取monthyear数字。
    • 如果月份数少于10,则水年为.dt.year,否则,水年为.dt.year + 1
    • 对于此DataFrame中的.apply行,
    • 比此answer282757函数快13倍。
import pandas as pd

# Load the data
df = pd.read_csv('WabashRiver_Flow.csv', parse_dates=['datetime'])

# drop na values
df = df.dropna()

# determine the water year
df['water_year'] = df.datetime.dt.year.where(df.datetime.dt.month < 10, df.datetime.dt.year + 1)

# display(df.head())
  agency_cd  site_no            datetime tz_cd  discharge_cfps  water_year
0      USGS  3335500 2001-10-01 00:00:00   EST            2610        2002
1      USGS  3335500 2001-10-01 01:00:00   EST            2610        2002
2      USGS  3335500 2001-10-01 02:00:00   EST            2610        2002
3      USGS  3335500 2001-10-01 03:00:00   EST            2630        2002
4      USGS  3335500 2001-10-01 04:00:00   EST            2630        2002

按水年计算平均排放量

annual_mean_discharge_rate = df.groupby('water_year')[['discharge_cfps']].mean()

# display(annual_mean_discharge_rate)
            discharge_cfps
water_year                
2002           9379.829589
2003           8678.468324
2004           8562.505005
2005           8928.776256
2006           6710.805312
2007          10331.564789
2008          10626.336623
2009           8972.046607
2010           5298.569557
2011          10519.540869
2012           9013.624424
2013           9007.924205
2014           9079.561658
2015          12267.393776
2016           6445.875810
2017          10240.721464

annual_mean_discharge_rate.plot.bar(figsize=(8, 6), xlabel='Water Year', ylabel='Discharge (cubic feet / sec)', legend=False)

enter image description here


%%timeit比较

import numpy as np

# function from other answer; updated because pd.datetime is deprecated
def assign_wy(row):
    if row.month>=10:
        return(row.year + 1)
    else:
        return(row.year)


%%timeit
df.datetime.dt.year.where(df.datetime.dt.month < 10, df.datetime.dt.year + 1)
[out]:
66.9 ms ± 1.67 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%%timeit
df.datetime.apply(lambda v: np.where(v.month >= 10, v.year + 1, v.year))
[out]:
1.38 s ± 23 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%%timeit
df.datetime.apply(lambda x: assign_wy(x))
[out]:
861 ms ± 9.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)