【问题标题】:pandas shift date using values from another column熊猫使用另一列中的值移动日期
【发布时间】:2016-12-23 05:54:51
【问题描述】:

制作测试数据的代码:

 import pandas as pd
 df = pd.DataFrame({'A': pd.date_range(start='1-1-2016',periods=5, freq='M')})
 df['B'] = df.A.dt.month
 print(df)

数据看起来像

   B          A
0  1     2016-01-31
1  2     2016-02-29
2  3     2016-03-31
3  4     2016-04-30
4  5     2016-05-31

如何将 A 列向后移动月数作为 B 列的值

大意

 df['A'] - pd.DateOffset(months=value_from_column_B)

【问题讨论】:

    标签: python date datetime pandas time-series


    【解决方案1】:

    这是一种组合日期数组 (NumPy datetime64s) 的矢量化方法 日期组件(如年、月、日):

    import numpy as np
    import pandas as pd
    
    def compose_date(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)
    
    df = pd.DataFrame({'A': pd.date_range(start='1-1-2016',periods=5, freq='M')})
    df['B'] = df['A'].dt.month
    df['C'] = compose_date(years=df['A'].dt.year, 
                           months=df['A'].dt.month-df['B'], 
                           days=df['A'].dt.day)
    print(df)
    #            A  B          C
    # 0 2016-01-31  1 2015-12-31
    # 1 2016-02-29  2 2015-12-29
    # 2 2016-03-31  3 2015-12-31
    # 3 2016-04-30  4 2015-12-30
    # 4 2016-05-31  5 2015-12-31
    

    In [135]: df = pd.DataFrame({'A': pd.date_range(start='1-1-2016', periods=10**3, freq='M')})
    
    In [136]: df['B'] = df['A'].dt.month
    
    In [137]: %timeit compose_date(years=df['A'].dt.year, months=df['A'].dt.month-df['B'], days=df['A'].dt.day)
    10 loops, best of 3: 41.2 ms per loop
    
    In [138]: %timeit df[['A', 'B']].apply(lambda x: x['A'] - pd.DateOffset(months=x['B']), axis=1)
    10 loops, best of 3: 169 ms per loop
    

    【讨论】:

      【解决方案2】:

      你可以试试:

      df['C'] = df[['A', 'B']].apply(lambda x: x['A'] - pd.DateOffset(months=x['B']), axis=1)
      

      【讨论】:

        【解决方案3】:

        B 转换为datetime.timedelta 对象。然后你可以简单地从任何日期对象中减去它。

        【讨论】:

        • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-04
        相关资源
        最近更新 更多