Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在数据框中移动日期(添加x个月)?_Python_Date_Pandas - Fatal编程技术网

Python 如何在数据框中移动日期(添加x个月)?

Python 如何在数据框中移动日期(添加x个月)?,python,date,pandas,Python,Date,Pandas,我有一个带有日期列的数据框 我知道如何按固定的月数移动日期(例如,在第x列中的所有日期上加上3个月);然而,我不知道如何将日期按月份进行移动,这不是固定的,而是数据帧的另一列 有什么想法吗 我复制了下面的一个最小示例。我得到的错误是: The truth value of a Series is ambiguous 非常感谢 import pandas as pd import numpy as np import datetime df = pd.DataFrame() df['year'

我有一个带有日期列的数据框

我知道如何按固定的月数移动日期(例如,在第x列中的所有日期上加上3个月);然而,我不知道如何将日期按月份进行移动,这不是固定的,而是数据帧的另一列

有什么想法吗

我复制了下面的一个最小示例。我得到的错误是:

The truth value of a Series is ambiguous
非常感谢

import pandas as pd
import numpy as np
import datetime

df = pd.DataFrame()
df['year'] = np.arange(2000,2010)
df['month'] = 3

df['mydate'] = pd.to_datetime(  (df.year * 10000 + df.month * 100 +1).apply(str), format='%Y%m%d')
df['month shift'] = np.arange(0,10)

# if I want to shift mydate by 3 months, I can convert it to DatetimeIndex and use dateOffset:
df['my date shifted by 3 months'] = pd.DatetimeIndex( df['mydate'] ) + pd.DateOffset(months = 3)

# however, how do I shift mydate by the number of months in the column 'month shift'?
#This does NOT work:
df['my date shifted'] = pd.DatetimeIndex( df['mydate'] ) + pd.DateOffset(months = df['month shift'])
print df

IIUC您可以使用轴=1的
应用

In [23]: df.apply(lambda x: x['mydate'] + pd.DateOffset(months = x['month shift']), axis=1)
Out[23]:
0   2000-03-01
1   2001-04-01
2   2002-05-01
3   2003-06-01
4   2004-07-01
5   2005-08-01
6   2006-09-01
7   2007-10-01
8   2008-11-01
9   2009-12-01
dtype: datetime64[ns]

Edchorn的解决方案确实比Anton Protopov的答案快得多,事实上,在我的用例中,它的执行时间是毫秒,而应用程序的执行时间是分钟。问题是Edchorn在评论中发布的解决方案给出了稍微不正确的结果。在示例中:

import pandas as pd
import numpy as np
import datetime

df = pd.DataFrame()
df['year'] = np.arange(2000,2010)
df['month'] = 3

df['mydate'] = pd.to_datetime((df.year * 10000 + df.month * 100 + 1).apply(str), format='%Y%m%d')
df['month shift'] = np.arange(0,10)
答案是:

df['my date shifted'] = df['mydate'] + pd.TimedeltaIndex( df['month shift'], unit='M')
给出:

可通过以下方法获得正确的溶液:

def set_to_month_begin(series):
    #Following doesn't work:
    #  res = series.dt.floor("MS")

    #This also doesn't work (it fails in case the date is already the first day of the month):
    #  res = series - pd.offsets.MonthBegin(1)

    res = pd.to_datetime(series).dt.normalize()
    res = res - pd.to_timedelta(res.dt.day - 1, unit='d')
    return res

def add_months(df, date_col, months_num_col):
    """This function adds the number of months specified per each row in `months_num_col` to date in `date_col`.
    This method is *significantly* faster than:
        df.apply(lambda x: x[date_col] + pd.DateOffset(months = x[months_num_col]), axis=1)
    """
    number_of_days_in_avg_month = 365.24 / 12
    time_delta = pd.TimedeltaIndex(df[months_num_col] * number_of_days_in_avg_month + 10, unit='D')
    return set_to_month_begin(df[date_col] + time_delta)

df['my date shifted'] = add_months(df, 'mydate', 'month shift')
这将产生以下结果:

“一”衬板使用:

df['my date shift']=(
df[“mydate”].values.astype(“datetime64[M]”)
+df[“月移”].values.astype(“timedelta64[M]”)
)

不确定这是否是您想要的:
df['mydate shift']=df['mydate']+pd.TimedeltaIndex(df['month shift'],unit='M')
?您可以添加预期的输出吗?@EdChum,您的建议有效,谢谢!然而,究竟为什么你的代码有效而我的代码无效?它是否在任何地方都有记录,或者熊猫的语法在约会时是极其反复无常的?与Matlab和SQL相比,我在语法和文档中都找不到任何一致性,我正在构造一个timedeltaindex并添加另一个系列,
pd.DateOffset
只构造一个标量
DateOffset
对象,它不能构造一个系列。请注意,第二行的日期可能不是您想要的,因此我的问题实际上我没有注意到。这是因为熊猫把一个月变为30天吗?理想情况下不是,我需要2001年3月1日+1个月才能成为2001年4月1日;这些标题需要精确,因为我需要按它们分组。你的代码可以调整以得到这个结果吗?谢谢。这是可行的,但EdChum的解决方案似乎更快;我想这可能是因为运行apply语句的速度比较慢。方法是矢量化的,因为它构造了一个索引并将其添加到另一个系列中,但它可能不是您想要的,因为
2001-03-31
,我已经解释过了。因为我的数据帧不是很大,所以现在我将使用Anton的解决方案。我确实想知道是否有一种方法可以矢量化——当安东的代码应用于大型数据帧时,使其更快。伙计们,非常感谢你们两个!