设置如下:

我有两个(整数索引)列,startmonth_deltastart具有时间戳(其内部类型是np.datetime64[ns]),而month_delta是整数。

我想快速生成由start中的每个日期时间组成的列,并由month_delta中的相应月份数抵消。我该怎么做呢?

我尝试过的事情不起作用:

  • apply太慢。
  • 您不能将一系列DateOffset对象添加到一系列datetime64[ns] dtype(或DatetimeIndex)中。
  • 您也不能使用一系列timedelta64对象。 Pandas 默默地将基于月的时间增量转换为约30天长的基于纳秒的时间增量。 (赞!发生了什么事而没有默默失败?)

  • 目前,我正在遍历month_delta的所有不同值,并在我创建的tshift的相关部分上按该数量执行DatetimeIndex,但这是一个可怕的麻烦:
    new_dates = pd.Series(pd.Timestamp.now(), index=start.index)
    date_index = pd.DatetimeIndex(start)
    for i in xrange(month_delta.max()):
        mask = (month_delta == i)
        cur_dates = pd.Series(index=date_index[mask]).tshift(i, freq='M').index
        new_dates[mask] = cur_dates
    

    !有什么建议么?

    最佳答案

    这是一种无需调用apply的方法(通过将NumPy datetime64s与timedelta64s相加):

    import pandas as pd
    import numpy as np
    np.random.seed(1)
    
    def combine64(years, months=1, days=1, weeks=None, hours=None, minutes=None,
                  seconds=None, milliseconds=None, microseconds=None, nanoseconds=None):
        years = np.asarray(years) - 1970
        months = np.asarray(months) - 1
        days = np.asarray(days) - 1
        types = ('<M8[Y]', '<m8[M]', '<m8[D]', '<m8[W]', '<m8[h]',
                 '<m8[m]', '<m8[s]', '<m8[ms]', '<m8[us]', '<m8[ns]')
        vals = (years, months, days, weeks, hours, minutes, seconds,
                milliseconds, microseconds, nanoseconds)
        return sum(np.asarray(v, dtype=t) for t, v in zip(types, vals)
                   if v is not None)
    
    def year(dates):
        "Return an array of the years given an array of datetime64s"
        return dates.astype('M8[Y]').astype('i8') + 1970
    
    def month(dates):
        "Return an array of the months given an array of datetime64s"
        return dates.astype('M8[M]').astype('i8') % 12 + 1
    
    def day(dates):
        "Return an array of the days of the month given an array of datetime64s"
        return (dates - dates.astype('M8[M]')) / np.timedelta64(1, 'D') + 1
    
    N = 10
    df = pd.DataFrame({
       'start': pd.date_range('2000-1-25', periods=N, freq='D'),
       'months': np.random.randint(12, size=N)})
    start = df['start'].values
    df['new_date'] = combine64(year(start), months=month(start) + df['months'],
                               days=day(start))
    
    print(df)
    

    产量
       months      start   new_date
    0       5 2000-01-25 2000-06-25
    1      11 2000-01-26 2000-12-26
    2       8 2000-01-27 2000-09-27
    3       9 2000-01-28 2000-10-28
    4      11 2000-01-29 2000-12-29
    5       5 2000-01-30 2000-06-30
    6       0 2000-01-31 2000-01-31
    7       0 2000-02-01 2000-02-01
    8       1 2000-02-02 2000-03-02
    9       7 2000-02-03 2000-09-03
    

    关于python - Pandas :快速将可变的月数添加到时间戳列中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26661880/

    10-10 21:15
    查看更多