【问题标题】:Easy way to fix wrong year (y2k bug) using pandas使用 pandas 修复错误年份(y2k 错误)的简单方法
【发布时间】:2022-10-20 20:28:52
【问题描述】:

我有一个数据库,其中有一列名为 ['birth_date'],已使用以下方法转换字符串 -> 日期:

dataCopy.loc[:,'birth_date'] = dataCopy['birth_date'].astype('datetime64[ns]')

我还转换了我的数据库的其他列。 所以,正如你们中的一些人知道的那样,当 python 看到像 mm/dd/69 及以下这样的日期时,2 位数的年份日期(mm/dd/yy 或其他)存在问题,它假定年份是 2069 年而不是 1969 年。 问题是我需要用另一列减去此列,以选择我的客户取消服务时的年龄。例:他1969年出生,2019年取消服务,所以53岁。我已经知道我该怎么做:

dataCopy['idade'] = (dataCopy['deleted_at'].dt.year - dataCopy['birth_date'].dt.year)

但首先我需要修正错误的年份。使用格式(y%m%d 和变体)不起作用。我的意思是,他们工作,但他们不会修正错误的年份。我是初学者,已经尝试过我在 Stack 上看到的功能,但我无法修改它以匹配我的问题(而且我没有 100% 理解它)。我很感激任何帮助。

【问题讨论】:

    标签: python pandas dataframe jupyter-notebook y2k


    【解决方案1】:

    您需要创建一个自定义函数并将其映射到birth_date 列。

    您可以决定一个截止年份(例如 40 年),将其分类为 19 世纪,低于其分类为 20 世纪。例如,62 将转换为 1962 年,32 将转换为 2032。

    下面的代码创建了转​​换日期字符串的自定义函数。

    import pandas as pd
    import datetime as dt
    
    
    def custom_date_function(date_string: str) -> dt.date:
        """
        Convert date string to date object
        """
        # Note that the first 8 character is the date without the time
        # Selecting the first 8 character
        # And then splitting the string using '/' to year, month and date
        date_components = date_string[0:8].split('/')
    
        # All number greater than 40 will be changed to 19th century
        # Else to 20th century
        # You may change the cutoff from 40
    
        if int(date_components[2]) >= 40:
            year = 1900 + int(date_components[2])
        else:
            year = 2000 + int(date_components[2])
    
        return dt.date(year=year, month=int(date_components[0]), day=int(date_components[1]))
    

    创建自定义函数后,您可以在birth_date 列中使用它。

    # Example Code of applying the custom function on birth_date DataFrame column
    
    # Creating an example DataFrame with birth_date column
    df_dict = {'birth_date': ['11/22/67', '03/23/69', '11/22/27']}
    dataCopy = pd.DataFrame(df_dict)
    
    # Applying the function on birth_date DataFrame column
    out = dataCopy['birth_date'].apply(custom_date_function)
    print(out)
    

    birth_date 列有可能已经是一个日期对象。在这种情况下,您需要在应用custom_date_function 之前将其转换为字符串。

    【讨论】:

    • 很抱歉,我忘了提及所有 [birth_date] 行也在使用时间“07/10/74 12:00 AM”。另外我不理解字典部分,它是代码的一部分还是只是示例?在函数内部,我应该将 datetime 转换为 date 对象(撤消我所做的)?为什么?
    • 我以某种方式使用字典来创建 pandas DataFrame。这只是一个例子。在您的情况下,您可以跳过该部分。日期对象很有用,因为您可以进行简单的算术运算,例如查找两个日期之间的年、日等差异。我已经编辑了答案以使其适用于您的日期格式。
    【解决方案2】:

    比@Fahids 解决方案略简单,但使用相同的条件方法

    import pandas as pd
    
    original_dates = pd.Series(['01-01-34', '01-01-66', '01-01-19', '01-01-20'])
    
    # define latest possible date the data can be from
    cutoff_date = pd.to_datetime('01-01-2020')
    # convert dates to pandas time stamps
    fixed_dates = pd.to_datetime(original_dates, format='%m-%d-%y')
    # substract 100 years from each time stamp > cutoff date
    fixed_dates.loc[fixed_dates > cutoff_date] -= pd.DateOffset(years=100)
    print(fixed_dates)
    

    输出

    0   1934-01-01
    1   1966-01-01
    2   2019-01-01
    3   2020-01-01
    dtype: datetime64[ns]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-18
      • 1970-01-01
      • 1970-01-01
      • 2020-12-23
      • 2012-12-03
      • 1970-01-01
      • 1970-01-01
      • 2017-03-18
      相关资源
      最近更新 更多