【问题标题】:Modify Spanish month in date column修改日期列中的西班牙月份
【发布时间】:2021-11-26 23:40:37
【问题描述】:

我有一个从 excel 文件中读取的 Pandas 数据框,该文件是西班牙语,并且在日期列中包含所有月份,如下所示:

"11/ene/2021, 22/feb/, 04/mar/2021, 15/abr/2021, 13/may/2021, 16/jun/2021, 14/jul/2021, ...."

即,每个月是一个由 3 个字符组成的字符串,后跟年份,日期在格式的第一个位置,d/m/y

因为它是西班牙语,所以我无法用日期时间解析,所以我想我可以用正则表达式搜索月份并替换为存储在字典中的与月份数相等的值。

我认为可行的正则表达式是:

r'\d+\/[a-z]{3}\/\d+'

在 Pandas 中有没有办法做到这一点?

【问题讨论】:

    标签: python regex pandas dataframe


    【解决方案1】:

    @Wiktor 的回答完全正确。但是,我认为以下实现更容易阅读:

    months = ['ene','feb','mar','abr','may','jun','jul','ago','sep','oct','nov','dic']
    d = dict(zip(months, np.arange(1, 13)))
    

    那么你可以简单地使用pandas.to_datetime:

    pd.to_datetime(df['dates'].replace(d, regex=True))
    

    【讨论】:

    • 非常感谢,但是a是什么意思?
    • 对不起,我编辑了答案。
    【解决方案2】:

    你可以使用

    import pandas as pd
    months = {'ene': '01', 'feb': '02', 'mar':'03', 'abr':'04', 'may': '05', 'jun': '06','jul': '07','ago': '08','sep': '09','oct': '10','nov': '11','dic': '12'}
    df = pd.DataFrame({'dates': ['11/ene/2021', '22/feb/2021', '04/mar/2021', '15/abr/2021', '13/may/2021', '16/jun/2021', '14/jul/2021']})
    # => df
    #           dates
    #  0  11/ene/2021
    #  1  22/feb/2021
    #  2  04/mar/2021
    #  3  15/abr/2021
    #  4  13/may/2021
    #  5  16/jun/2021
    #  6  14/jul/2021
    pd.to_datetime(df['dates'].str.replace(rf'\b(?:{"|".join([x for x in months])})\b', lambda x: months[x.group()], regex=True))
    # => 0   2021-11-01
    #    1   2021-02-22
    #    2   2021-04-03
    #    3   2021-04-15
    #    4   2021-05-13
    #    5   2021-06-16
    #    6   2021-07-14
    #    Name: dates, dtype: datetime64[ns]
    

    在这里,rf'\b(?:{"|".join([x for x in months])})\b' 创建了一个类似于 \b(?:ene|feb|mar|abr|may|jun|jul|ago|sep|oct|nov|dic)\b 的正则表达式,它匹配 3 个字母的西班牙月份缩写。一旦在字符串中匹配,匹配的文本将用作months 字典的键以获得适当的值。结果被传递给pd.to_datetime 函数。

    【讨论】:

    • 非常感谢,我不明白它是如何工作的,你在正则表达式中做了一个列表理解?
    • @TFM 不,我从 f 字符串中的字典键创建了一个正则表达式模式(允许变量扩展的字符串文字,也就是字符串插值)。 [x for x in months] 获取字典键列表,"|".join(...) 使它们成为单个管道分隔的字符串。见Match a whole word in a string using dynamic regex
    • 仅供参考:要使其不区分大小写,请使用.replace(rf'(?i)\b(?:{"|".join([x for x in months])})\b', lambda x: months[x.group().lower()], regex=True)
    【解决方案3】:

    我们可以将setlocale LC_TIME 改为西班牙语(es_ES),而不是自己实现此行为,然后to_datetime 将使用格式字符串按预期工作,因为strftime() and strptime() Behavior 是相对于语言环境的:

    import locale
    
    import pandas as pd
    
    # Use Spanish Locale
    locale.setlocale(locale.LC_TIME, 'es_ES')
    
    df = pd.DataFrame({
        'dates': ['11/ene/2021', '22/feb/2021', '04/mar/2021', '15/abr/2021',
                  '13/may/2021', '16/jun/2021', '14/jul/2021', '03/ago/2021',
                  '07/sep/2021', '27/oct/2021', '17/nov/2021', '29/dic/2021']
    })
    
    # Convert to DateTime using pattern
    # 2-digit day %d, locale month abbr %b, 4-digit year %Y
    df['converted_dates'] = pd.to_datetime(df['dates'], format='%d/%b/%Y')
    
    print(df)
    

    df:

              dates converted_dates
    0   11/ene/2021      2021-01-11
    1   22/feb/2021      2021-02-22
    2   04/mar/2021      2021-03-04
    3   15/abr/2021      2021-04-15
    4   13/may/2021      2021-05-13
    5   16/jun/2021      2021-06-16
    6   14/jul/2021      2021-07-14
    7   03/ago/2021      2021-08-03
    8   07/sep/2021      2021-09-07
    9   27/oct/2021      2021-10-27
    10  17/nov/2021      2021-11-17
    11  29/dic/2021      2021-12-29
    

    【讨论】:

      【解决方案4】:

      你可以这样使用:

      month = {'ene':'1','feb':'2','mar':'3','abr':'4'}
      df.columns = df.columns.to_series().replace(month, regex=True)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-20
        • 2020-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多