Python 如何按连续季节计算时间月数

Python 如何按连续季节计算时间月数,python,pandas,Python,Pandas,我有一个大的时间序列数据帧。该列已被格式化为datetime。比如 2017-10-06T00:00:00+00:00 2020-04-29 00:00:00+00:00 我想画出每个季节的样本数。比如下面。这些值是该季节的样本计数 1997 Winter 4 1997 Spring 8 1997 Summer 8 ... 2020 Winter 32 我做了一些搜索,发现我可以创建一个字典,将月份转换成季节。然而,自“实时冬季时间”以来最棘手的部分包含两年的数据。例如,1997年冬季实际上

我有一个大的时间序列数据帧。该列已被格式化为datetime。比如

2017-10-06T00:00:00+00:00
2020-04-29 00:00:00+00:00
我想画出每个季节的样本数。比如下面。这些值是该季节的样本计数

1997 Winter 4
1997 Spring 8
1997 Summer 8
...
2020 Winter 32
我做了一些搜索,发现我可以创建一个字典,将月份转换成季节。然而,自“实时冬季时间”以来最棘手的部分包含两年的数据。例如,1997年冬季实际上应包含1997年12月、1998年1月和1998年2月

请注意,我希望将“1997年1月、1997年2月”排除在1997年冬季之外,因为它们是“1996年冬季”

我想知道最有效的方法是什么?它不必命名为“1997年冬季”,只要计数数字从头到尾连续,任何索引都应该对我有效


非常感谢

有一种快速的方法可以解决这个问题,但它不是很正统。。。 创建一列“季节”,并使用np.where()指定季节。一开始,你说前三个月是冬天,下三个月是春天,依此类推。然后,对列应用shift(-1)将其向后移动一行。然后,你就有了自己的季节(只不过是拉斯南)。然后你可以用一种懒惰的方式解决你的问题。 如果你对代码不熟悉,告诉我,我会编辑它

编辑:

我假设日期在索引中。如果不是,您应该申请dt.month而不是.month。 我把它分解清楚

_condtion_spring = (df.index.month>=4)&(df.index.month<=6)
_condition_summer = (df.index.month>7)&(df.index.month<=9)
_condition_automn = (df.index.month>=10)@(df.index.month<=12)
df['Season'] = np.where(_condition_winter,'Winter',np.where(_condtion_spring,'Spring',np.where(_condition_summer,'Summer',np.where(_condition_automn,'Automn',np.nan))))
df['Season'] = df['Season'].shift(-1).fillna(method='ffill')

\u condition\u spring=(df.index.month>=4)和(df.index.month7)和(df.index.month=10)@(df.index.month=1)和(df.index.month=4)和(df.index.month=7)和(df.index.month=10)@(df.index.month=1)和(df.index.month=7)和(df.index.month=10)@(df.index.month有一种快速的解决方法,但不是很正统。。。
您创建一列“季节”,并使用np.where()指定季节。开始时,您说前3个月为冬季,下3个月为春季,依此类推。然后,您在列上应用移位(-1)将其向后移动一行。然后,您就有了季节(只需菲勒-拉斯南)。然后,您可以用一种懒惰的方式解决您的问题。
如果你对代码不熟悉,告诉我,我会编辑它

编辑:

我假设日期在索引中。如果不是,则应该应用dt.month而不是.month。 我把它分解清楚

_condtion_spring = (df.index.month>=4)&(df.index.month<=6)
_condition_summer = (df.index.month>7)&(df.index.month<=9)
_condition_automn = (df.index.month>=10)@(df.index.month<=12)
df['Season'] = np.where(_condition_winter,'Winter',np.where(_condtion_spring,'Spring',np.where(_condition_summer,'Summer',np.where(_condition_automn,'Automn',np.nan))))
df['Season'] = df['Season'].shift(-1).fillna(method='ffill')

\u condition\u spring=(df.index.month>=4)和(df.index.month7)和(df.index.month=10)@(df.index.month=1)和(df.index.month=4)和(df.index.month=7)和(df.index.month=10)@(df.index.month=1)和(df.index.month=7)和(df.index.month=10)@(df.index.month我认为您应该创建一个lambda函数,它通过月和日的值选择正确的季节

def seasons(date):
    m = date.month
    d = date.day
    season=None
    if (3==m and d>=21) or m==4 or m==5 or (m==6 and 20<=d):
        season = 'spring'
    elif (6==m and d>=21 ) or m==7 or m==8 or (m==9 and 20<=d):
        season = 'sommer'
    elif (9==m and d>=21 ) or m==10 or m==11 or (m==12 and 20<=d):
        season = 'autumn'
    elif (12==m and d>=21 ) or m==1 or m==2 or (m==3 and 20<=d):
        season = 'winter'
    return season

df['season'] = df.apply(lambda x: seasons(x['date']), axis=1)
def季节(日期):
m=日期。月份
d=日期
季节=无

如果(3==m和d>=21)或m==4或m==5或(m==6和20=21)或m==7或m==8或(m==9和20=21)或m==10或m==11或(m==12和20=21)或m==1或m==2或(m==3和20我认为您应该创建一个lambda函数,通过月和日的值选择正确的季节

def seasons(date):
    m = date.month
    d = date.day
    season=None
    if (3==m and d>=21) or m==4 or m==5 or (m==6 and 20<=d):
        season = 'spring'
    elif (6==m and d>=21 ) or m==7 or m==8 or (m==9 and 20<=d):
        season = 'sommer'
    elif (9==m and d>=21 ) or m==10 or m==11 or (m==12 and 20<=d):
        season = 'autumn'
    elif (12==m and d>=21 ) or m==1 or m==2 or (m==3 and 20<=d):
        season = 'winter'
    return season

df['season'] = df.apply(lambda x: seasons(x['date']), axis=1)
def季节(日期):
m=日期。月份
d=日期
季节=无

如果(3==m和d>=21)或m==4或m==5或(m==6和20=21)或m==7或m==8或(m==9和20=21)或m==10或m==11或(m==12和20=21)或m==1或m==2或(m==3和20我找到了另一个解决方法。所以我想把它留在这里

  • 所有样品1个月后轮班
  • 逐月附上季节
  • 然后你可以用你想要的任何方式处理这些样品
  • 如果您对其进行编码,它可能如下所示:

    from dateutil.relativedelta import *
        
    df.loc[:, 'shift_time'] = df.apply(lambda x: x['real_datetime'] + relativedelta(months=+1), axis=1)
    df.loc[:, 'season'] = df['shift_time'].dt.quarter
    grouped = df.groupby([(df['shift_time'].dt.year), (df['season'])]).count()
    

    我找到了另一种变通方法,所以我想把它留在这里

  • 所有样品1个月后轮班
  • 逐月附上季节
  • 然后你可以用你想要的任何方式处理这些样品
  • 如果您对其进行编码,它可能如下所示:

    from dateutil.relativedelta import *
        
    df.loc[:, 'shift_time'] = df.apply(lambda x: x['real_datetime'] + relativedelta(months=+1), axis=1)
    df.loc[:, 'season'] = df['shift_time'].dt.quarter
    grouped = df.groupby([(df['shift_time'].dt.year), (df['season'])]).count()
    

    是的,你能提供代码吗?我相信这对其他人也会有帮助!或者我认为有另一种方法,在一个月后转移每个样本。然后我可以根据季度对它们进行分组。你怎么看?我已经编辑了它。告诉我这是否是你所想的。嗨,我需要在使用t之前按日期时间对数据帧进行排序吗hat代码?如果在特定月份没有找到样本,会不会导致问题?@Xudong,我不确定是否理解您的问题。我编辑了一个完整的示例。我假设1984年冬季是从1983年12月到1984年2月。这是您想要的吗?例如,编辑1984年冬季的样本总数?是的,请提供code?我相信这对其他人也会有帮助!或者我认为有另一种方法,在一个月后对每个样本进行移位。然后我可以根据季度对它们进行分组。你怎么看?我已经编辑了它。告诉我这是否是你所想的。嗨,我需要在使用代码之前按日期时间对数据帧进行排序吗?如果没有呢在某个特定的月份,是否会引起问题?@Xudong,我不确定是否理解您的问题。我编辑了一个完整的示例。我假设1984年冬季是从1983年12月到1984年2月。这是您想要的吗?例如,编辑1984年冬季的样本总数?