You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python解析pandas数据框中极度模糊的艺术创作日期?

太懂你这种对着一堆格式乱七八糟的艺术品日期挠头的感觉了!自己写Transformer类啃了好几天,确实不如直接用现成工具香——Python生态里有几个专门对付这种模糊、非标准化日期的库,刚好适配你遇到的所有场景,给你梳理一下:

可用的Python工具推荐

1. dateparser - 处理多格式模糊日期的首选

这个库对非标准日期的兼容性拉满,能自动识别circa/c./ca.这类模糊前缀,世纪表述、年代范围、多日期分隔(分号/逗号)甚至BCE/CE纪年都不在话下。

给你整个适配你场景的示例:

import dateparser
import pandas as pd

# 你的日期样本
date_samples = [
    "1998", "circa 1995", "c. 2003-5", "March 2, 1904",
    "1st quarter of 19th century", "19th to 20th century",
    "ca. late 19th and early 20th Century BCE", "500",
    "206 BCE-240 CE", "1995-99", "designed 1950, produced 1969",
    "designed 1935, produced circa 1946-1968", "1990; and 1989",
    "1975/97", "no date", "n.d.", "mid 1900s", "late 1940's"
]

def parse_art_date(date_str):
    # 处理无日期的情况
    if date_str.lower() in ["no date", "n.d."]:
        return None
    # 针对designed/produced这类多时间节点的情况,提取并解析每个日期
    if "designed" in date_str or "produced" in date_str:
        # 拆分出每个时间节点的日期部分
        date_parts = []
        for segment in date_str.split(','):
            if any(kw in segment for kw in ["designed", "produced"]):
                # 提取日期字符串(比如"designed 1950"里的"1950")
                date_text = ' '.join(segment.split()[1:])
                date_parts.append(dateparser.parse(date_text))
        return tuple(date_parts)
    # 处理普通模糊日期
    return dateparser.parse(date_str)

# 应用到DataFrame
df = pd.DataFrame({"creation_date": date_samples})
df["parsed_dates"] = df["creation_date"].apply(parse_art_date)

2. parsedatetime - 专攻自然语言风格日期

这个库对“1st quarter of 19th century”“mid 1900s”“late 1940's”这类自然语言化的日期描述解析更精准,会返回结构化的datetime对象,适合侧重语义的场景。

示例代码:

import parsedatetime as pdt
cal = pdt.Calendar()

def parse_natural_date(date_str):
    if date_str.lower() in ["no date", "n.d."]:
        return None
    # 尝试自然语言解析
    result, status = cal.parseDT(date_str)
    if status == 1:  # 解析成功
        return result
    # 解析失败就fallback到dateparser
    return dateparser.parse(date_str)

3. 正则+日期库组合 - 搞定极端特殊格式

如果上面的库对“1937-42/48”“1975/97”这类奇葩格式处理不够精准,你可以先用正则提取核心日期片段,再交给日期库解析:

import re
import dateparser

def parse_special_dates(date_str):
    # 处理范围日期(比如1995-99、206 BCE-240 CE)
    range_match = re.match(r"(\d+.*?)-(\d+.*)", date_str)
    if range_match:
        start = dateparser.parse(range_match.group(1))
        end = dateparser.parse(range_match.group(2))
        return (start, end)
    # 处理斜杠分隔的日期(比如1975/97 -> 1975、1997)
    slash_match = re.match(r"(\d{4})/(\d{2})", date_str)
    if slash_match:
        year1 = slash_match.group(1)
        year2 = f"{year1[:2]}{slash_match.group(2)}"
        return (dateparser.parse(year1), dateparser.parse(year2))
    # 其他情况交给dateparser
    return dateparser.parse(date_str)

4. 历史日期(BCE/CE)的精准处理

dateparser已经支持BCE/CE解析,但如果需要更严谨的历史年代转换,可以用arrow库,它对公元前/公元后日期的处理更专业:

import arrow

def parse_historical_date(date_str):
    try:
        return arrow.get(date_str).datetime
    except:
        # 解析失败fallback
        return dateparser.parse(date_str)
额外实用建议
  • 对于包含多个时间节点的字符串(比如designed/produced),可以考虑把解析结果拆成单独的列(design_date、production_date),方便后续分析。
  • 无日期条目(no date/n.d.)统一标记为None,避免干扰后续数据统计。
  • 可以把这些解析函数做成一个流水线:先试parsedatetime,失败用dateparser,最后用正则兜底,最大化覆盖所有场景。

内容的提问来源于stack exchange,提问作者Austin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:44:59