我有一个包含两个时间列的Pandas df。这些列包含年度事件的yyyy-mm-dd。
如何计算所有年份事件发生的平均mm-dd?
我想这涉及计数(每行)实际日期和一年中1月1日之间的天数,但是我看不到如何有效地使用Pandas。
谢谢!
MapShapeSelectionBehavior
编辑: 完成重现错误的步骤:
dormancy1 greenup1 maturity1 senescence1 dormancy2 greenup2 maturity2 senescence2
8 2002-08-31 2002-04-27 2002-05-06 2002-08-21 NaT NaT NaT NaT
22 2003-09-17 2003-06-06 2003-06-15 2003-07-22 NaT NaT NaT NaT
36 2004-09-10 2004-04-20 2004-05-15 2004-05-24 NaT NaT NaT NaT
44 2005-08-13 2005-04-24 2005-06-29 2005-07-18 NaT NaT NaT NaT
74 2007-05-10 2007-03-13 2007-04-07 2007-05-01 NaT NaT NaT NaT
95 2009-09-18 2009-04-26 2009-05-06 2009-06-03 NaT NaT NaT NaT
113 2010-09-09 2010-05-29 2010-06-08 2010-07-19 NaT NaT NaT NaT
答案 0 :(得分:0)
这就是我要做的:
将数据转换为日期时间格式(如果尚未完成的话):
df['dormancy1'] = pd.to_datetime(df['dormancy1'])
df['greenup1'] = pd.to_datetime(df['greenup1'])
获取该行年份的1月1日(我假设您的事件在同一年发生):
df['1Jyear'] = df['dormancy1'].dt.year.apply(lambda x: dt.datetime(x, 1, 1))
这是您的数据框现在的外观:
df.head()
dormancy1 greenup1 1Jyear
0 2002-08-31 2002-04-27 2002-01-01
1 2003-09-17 2003-06-06 2003-01-01
2 2004-09-10 2004-04-20 2004-01-01
3 2005-08-13 2005-04-24 2005-01-01
4 2007-05-10 2007-03-13 2007-01-01
要获取每个事件的平均月份和日期:
df[['dormancy1', 'greenup1']].apply(lambda x: pd.to_datetime((x - df['1Jyear']).values.astype(np.int64).mean()).strftime('%m-%d'))
这将输出以下系列:
dormancy1 08-10
greenup1 04-30
让我知道这是否是必需的结果,希望对您有帮助。
我正在处理以下数据:
dormancy1 greenup1
0 2002-08-31 2002-04-27
1 2003-09-17 NaN
2 2004-09-10 2004-04-20
3 2005-08-13 2005-04-24
4 NaN 2007-03-13
5 2009-09-18 2009-04-26
6 2010-09-09 2010-05-29
7 2012-05-30 2012-05-04
8 NaN NaN
要计算每一行的年份(我得到在列中找到的第一年,因此我再次假设每个事件的年份都相同,但是如果不一致,则需要为每个事件计算不同的列事件):
def computeYear(row):
for i in row:
if pd.isna(i):
pass
else:
return dt.datetime(int(i.strftime('%Y')), 1, 1)
return np.nan
df['1Jyear'] = df[['dormancy1', 'greenup1']].apply(lambda row: computeYear(row), axis=1)
要获取结果(与以前相同):
df[['dormancy1', 'greenup1']].apply(lambda x: pd.to_datetime((x - df['1Jyear']).values.astype(np.int64).mean()).strftime('%m-%d'))
输出:
dormancy1 07-20
greenup1 04-17
dtype: object
答案 1 :(得分:0)
好的,现在您要在这里使用的是旧的 pandas.Series.dt.dayofyear
函数。这将告诉您特定日期一年中发生了多少天。这可能使您脑海中扫了一下,现在就在建立答案,但以防万一:
avg_day_dormancy1 = df['dormancy1'].dt.dayofyear.mean()
# Now let's add those days to a year to get an actual date
import datetime as dtt # You could do this in pandas, but this is quick and dirty
avg_date_dormancy1 = dtt.datetime.strptime('2000-01-01', '%Y-%m-%d') # E.g. get date in year 2000
avg_date_dormancy += dtt.timedelta(days=avg_day_dormancy1)
鉴于您提供的数据,我将dormancy1
的平均发生日期定为8月10日。例如,您也可以在.std()
系列上调用dayofyear
方法,并获得发生这些事件的95%置信区间。
答案 2 :(得分:0)
这是另一种方式。希望这会有所帮助
import pandas as pd
from datetime import datetime
计算这两个事件的平均一天时间
mean_greenup_DoY = df['greenup1'].apply(lambda x: datetime.strptime(x, '%Y-%m-%d').timetuple().tm_yday).mean()
mean_dormancy_DoY = df['dormancy1'].apply(lambda x: datetime.strptime(x, '%Y-%m-%d').timetuple().tm_yday).mean()
此方法首先将日期字符串转换为datetime对象,然后使用lambda函数中的逻辑查找一年中的某天,这意味着平均值()用于获取一年中的平均天。