【问题标题】:Make Datetime Series from separate year, month, and date columns in Pandas从 Pandas 中单独的年、月和日期列制作日期时间系列
【发布时间】:2019-04-23 12:08:50
【问题描述】:

我们如何使用 'Yr'、'Mo' 和 'Dy' 列来创建一个 Datetime 类型的新列并将其设置为 Pandas DataFrame 的索引?

【问题讨论】:

    标签: python pandas datetime dataframe


    【解决方案1】:

    首先,您应该将 Yr 转换为四位整数,即 1961 或 2061。这是明确的,如果您使用以下方法,则需要格式 YYYY-MM-DD。那是因为 Pandas 在 pandas/core/tools/datetimes.py 中使用了format='%Y%m%d'

    # From pandas/core/tools/datetimes.py, if you pass a DataFrame or dict
    values = to_datetime(values, format='%Y%m%d', errors=errors)
    

    所以,举个例子:

    from itertools import product
    
    import numpy as np
    import pandas as pd
    np.random.seed(444)
    
    datecols = ['Yr', 'Mo', 'Dy']
    mapper = dict(zip(datecols, ('year', 'month', 'day')))
    df = pd.DataFrame(list(product([61, 62], [1, 2], [1, 2, 3])),
                      columns=datecols)
    df['data'] = np.random.randn(len(df))
    

    这里是df

    In [11]: df                                                                                                                                                   
    Out[11]: 
        Yr  Mo  Dy      data
    0   61   1   1  0.357440
    1   61   1   2  0.377538
    2   61   1   3  1.382338
    3   61   2   1  1.175549
    4   61   2   2 -0.939276
    5   61   2   3 -1.143150
    6   62   1   1 -0.542440
    7   62   1   2 -0.548708
    8   62   1   3  0.208520
    9   62   2   1  0.212690
    10  62   2   2  1.268021
    11  62   2   3 -0.807303
    

    为了简单起见,我们假设真实范围是 1920 年以后,即:

    In [16]: yr = df['Yr']                                                                                                                                        
    
    In [17]: df['Yr'] = np.where(yr <= 20, 2000 + yr, 1900 + yr)                                                                                                  
    
    In [18]: df                                                                                                                                                   
    Out[18]: 
          Yr  Mo  Dy      data
    0   1961   1   1  0.357440
    1   1961   1   2  0.377538
    2   1961   1   3  1.382338
    3   1961   2   1  1.175549
    4   1961   2   2 -0.939276
    5   1961   2   3 -1.143150
    6   1962   1   1 -0.542440
    7   1962   1   2 -0.548708
    8   1962   1   3  0.208520
    9   1962   2   1  0.212690
    10  1962   2   2  1.268021
    11  1962   2   3 -0.807303
    

    您需要做的第二件事是重命名列;如果您将映射或 DataFrame 传递给pd.to_datetime(),Pandas 对此非常严格。这是该步骤和结果:

    In [21]: df.index = pd.to_datetime(df[datecols].rename(columns=mapper))                                                                                       
    
    In [22]: df                                                                                                                                                   
    Out[22]: 
                  Yr  Mo  Dy      data
    1961-01-01  1961   1   1  0.357440
    1961-01-02  1961   1   2  0.377538
    1961-01-03  1961   1   3  1.382338
    1961-02-01  1961   2   1  1.175549
    1961-02-02  1961   2   2 -0.939276
    1961-02-03  1961   2   3 -1.143150
    1962-01-01  1962   1   1 -0.542440
    1962-01-02  1962   1   2 -0.548708
    1962-01-03  1962   1   3  0.208520
    1962-02-01  1962   2   1  0.212690
    1962-02-02  1962   2   2  1.268021
    1962-02-03  1962   2   3 -0.807303
    

    最后,这里是通过将列连接为字符串的替代方法:

    In [27]: as_str = df[datecols].astype(str)   
    In [30]: pd.to_datetime( 
        ...:     as_str['Yr'] + '-' + as_str['Mo'] +'-' + as_str['Dy'], 
        ...:     format='%y-%m-%d' 
        ...:    )                                                                                                                                                 
    Out[30]: 
    0    2061-01-01
    1    2061-01-02
    2    2061-01-03
    3    2061-02-01
    4    2061-02-02
    5    2061-02-03
    6    2062-01-01
    7    2062-01-02
    8    2062-01-03
    9    2062-02-01
    10   2062-02-02
    11   2062-02-03
    dtype: datetime64[ns]
    

    再次注意,这将为您假设世纪。如果要明确,则需要按照与上述相同的方法在定义 as_str 之前添加正确的世纪。

    【讨论】:

      【解决方案2】:

      正如布拉德所指出的,这就是我修复它的方法

      def adjustyear(x):
          if x >= 1800:
              x = 1900 + x
          else:
              x = 2000 + x
          return x
      
      def parsefunc(x):
          yearmodified = adjustyear(x['Yr'])
          print(yearmodified)
          datetimestr = str(yearmodified)+str(x['Mo'])+str(x['Dy'])
          return pd.to_datetime(datetimestr, format='%Y%m%d', errors='ignore')
      
      data['newindex'] = data.apply(parsefunc, axis=1)
      data.index = data['newindex']
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-21
        • 1970-01-01
        • 2019-06-26
        • 1970-01-01
        • 2018-10-15
        • 2014-09-28
        相关资源
        最近更新 更多