python - 处理日期不正确的数据,例如 2 月 30 日
问题描述
在尝试处理大量以 CSV 格式提供的银行账户对账单时,我意识到有些日期不正确(2 月 30 日,这是不可能的)。
所以这个片段失败 [1] 告诉我某些日期不正确:
df_from_csv = pd.read_csv( csv_filename
, encoding='cp1252'
, sep=";"
, thousands='.', decimal=","
, dayfirst=True
, parse_dates=['Buchungstag', 'Wertstellung']
)
我当然可以预处理这些 CSV 文件,并将 2 月 30 日替换为 2 月 28 日(或当年 2 月结束的任何时间)。
但是有没有办法在熊猫中做到这一点,同时导入?像“如果此列失败,请将其设置为 X”?
样本行
775945;28.02.2018;30.02.2018;;901;"Zinsen"
如您所见,日期30.02.2018
不正确,因为没有 2 月 30 日。但这似乎是德国的一个已知问题。见[2]。
[1] 这是错误消息:
ValueError: day is out of range for month
解决方案
这是我解决它的方法:
我添加了一个自定义日期解析器:
import calendar
def mydateparser(dat_str):
"""Given a date like `30.02.2020` create a correct date `28.02.2020`"""
if dat_str.startswith("30.02"):
(d, m, y) = [int(el) for el in dat_str.split(".")]
# This here will get the first and last days in a given year/month:
(first, last) = calendar.monthrange(y, m)
# Use the correct last day (`last`) in creating a new datestring:
dat_str = f"{last:02d}.{m:02d}.{y}"
return pd.datetime.strptime(dat_str, "%d.%m.%Y")
# and used it in `read_csv`
for csv_filename in glob.glob(f"{path}/*.csv"):
# read csv into DataFrame
df_from_csv = pd.read_csv(csv_filename,
encoding='cp1252',
sep=";",
thousands='.', decimal=",",
dayfirst=True,
parse_dates=['Buchungstag', 'Wertstellung'],
date_parser=mydateparser
)
这使我可以修复那些不正确的“30.02.XX”日期,并允许 pandas 将这两个日期列 ( ['Buchungstag', 'Wertstellung']
) 转换为日期,而不是对象。
推荐阅读
- domain-driven-design - 应用服务的要点?
- r - tidyr::spread tidyr::pivot_wider 每个键有多个不同的值
- log4j - java - 为什么我在带有jasper报告的java中收到log4j警告?
- php - 作曲家自动加载找不到类错误
- json - jsonschema:对象数组中的唯一属性
- android - 我的应用程序反复请求权限,尽管用户授予了它
- ios - 集合视图中不同部分的不同布局
- ruby-on-rails - Rails 5控制器中的范围嵌套关联
- r - R - rlm - R 中稳健回归后的 p 值和 R 平方
- react-native - React-native-document-picker 在 android 中不起作用