我有一个大型数据框,其中包含一个(挪威)社会安全号码。可以通过特殊算法从这个数字中获取出生日期。然而,不时会有一个非法的社会安全号码潜入数据库破坏计算。
我想做的是标记每一行具有非法社会安全号码的行,以及一条显示所引发错误的日志消息。
考虑以下构造的示例
import pandas as pd
from datetime import date
sample_data = pd.DataFrame({'id' : [1, 2, 3], \
'sec_num' : [19790116, 19480631, 19861220]})
# The actual algorithm transforming the sec number is more complicated
# this is just for illustration purposes
def int2date(argdate: int):
try:
year = int(argdate / 10000)
month = int((argdate % 10000) / 100)
day = int(argdate % 100)
return date(year, month, day)
except ValueError:
raise ValueError("Value:{0} not a legal date.".format(argdate))
我想创建以下输出
id sec_num date_of_birth is_in_error error_msg
0 1 19790116 1979-01-16 False
1 2 19480631 None True 19480631 is not a legal date
2 3 19861220 1986-12-20 False
我试过了
try:
sample_data['date_of_birth'] = [int2date(sec_num) for \
sec_num in sample_data['sec_num']]
sample_data['is_in_error'] = False
sample_data['error_msg'] = ''
except ValueError as e:
sample_data['is_in_error'] = True
sample_data['error_msg'] = str(e)
但这会产生这个
id sec_num is_in_error error_msg
0 1 19790116 True Value:19480631 not a legal date.
1 2 19480631 True Value:19480631 not a legal date.
2 3 19861220 True Value:19480631 not a legal date.
我想问题是我在一个操作中分配了 date_of_birth
列,在另一个操作中分配了错误。我不确定如何模拟地捕获和创建 is_in_error
和 error_msg
列。
最佳答案
发生这种情况是因为您填充数据框的方式。
sample_data['error_msg'] = str(e)
实际上会用 str(e)
覆盖整个列。
这可能是最有效的方法:
def int2date(argdate: int):
try:
year = int(argdate / 10000)
month = int((argdate % 10000) / 100)
day = int(argdate % 100)
return date(year, month, day)
except ValueError as e:
pass # you could write the row and the error to your logs here
df['date_of_birth'] = df.sec_num.apply(int2date)
df['is_in_error'] = df.date_of_birth.isnull()
但是,如果您还想将错误写入数据框,则可以使用这种方法,尽管它可能会慢得多(对此可能有更快的解决方案)。
df['date_of_birth'] = None
df['error_msg'] = None
df['is_in_error'] = False
for i, row in df.iterrows():
try:
date_of_birth = int2date(row['sec_num'])
df.set_value(i, 'date_of_birth', date_of_birth)
except ValueError as e:
df.set_value(i, 'is_in_error', True)
df.set_value(i, 'error_msg', str(e))
这会分别处理每一行,并且只会将错误写入正确的索引,而不是更新整个列。
关于python - 引发错误后如何在数据框中标记损坏的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46197084/