我是一名熊猫新手,并试图在年内进行比较多年,其中包括闰年。他们'dayofyear'功能是伟大的..除了有闰年。 这是我的代码:
df = pd.read_csv('myfile.csv')
df['Date'] = pd.to_datetime(df['Date'])
df['Day_of_Year'] = df['Date'].dt.dayofyear
## Deal with 2008 leap year
df_2008_1st = df[(df['Date'] >= '01/01/2008')
& (df['Date'] <= '02/28/2008')]
df_2008_2nd = df[(df['Date'] >= '03/01/2008')
& (df['Date'] <= '12/31/2008')]
df_2008_2nd['Day_of_Year'] = df_2008_2nd['Day_of_Year'] -1
df_2008 = df_2008_1st.append(df_2008_2nd)
我的问题是两部分,一部分可能是主观的 首先,必须有一种更好,更短,更快的方式来编写这段代码。 这是有效的,但是对于我确信更容易做的事情来说,它有很多编码。
其次,我要用一年一年的销售数据每日比较图表。我不知道标准做法是什么 - 阅读闰年的代码建议我可以找到一个关于如何在实践中处理这个问题的快速指南。有人愿意分享他们在实践中处理闰日数据的方式吗?
谢谢你, 我
答案 0 :(得分:1)
我认为这可以通过不创建和合并新的DataFrame来略微简化您的代码。
df = pd.read_csv('myfile.csv')
df['Date'] = pd.to_datetime(df['Date'])
df = df[(df['Date'] != '02/29/2008')] # this removes Feb, 29
df['Day_of_Year'] = df['Date'].dt.dayofyear
mask = (df['Date'] >= '03/01/2008') & (df['Date'] <= '12/31/2008')
df.loc[mask, 'Day_of_Year'] = df.loc[mask, 'Day_of_Year'] - 1
df.iloc[56:63]
Date Day_of_Year
56 2008-02-26 57
57 2008-02-27 58
58 2008-02-28 59
60 2008-03-01 60
61 2008-03-02 61
62 2008-03-03 62
63 2008-03-04 63
根据您的情况是否允许,我会使用日期作为索引,这使得切片和其他基于日期的分析更加容易。 (注意:读取csv时可以完成索引和日期解析。)
df1 = pd.read_csv('myfile.csv', index_col='Date',
parse_dates=True, infer_datetime_format=True)
df1 = df1[(df1.index != '02/29/2008')] # this removes Feb, 29
df1['Day_of_Year'] = df1.index.dayofyear
df1.loc['03/01/2008':'12/31/2008', 'Day_of_Year'] = df1.loc['03/01/2008':'12/31/2008', 'Day_of_Year'] - 1
然后您可以使用这样的切片进行检查:
df1.loc['02/26/2008':'3/3/2008']
返回:
Day_of_Year
Date
2008-02-26 57
2008-02-27 58
2008-02-28 59
2008-03-01 60
2008-03-02 61
2008-03-03 62
至于如何处理闰日,这可能更多是商业决策,所以它可能无法在这里得到解答。但是这个问题可能会有所帮助:Accounting for leap year in comparing year to year sales
答案 1 :(得分:1)
你可以像这样组成每一天的任意索引:
df['Day_of_Year'] = df['Date'].dt.month*31 + df['Date'].dt.day
通过这种方式,具有相同“Day_of_Year”值的条目将对应于相同的日期,而与闰年无关。