4

我想使用大期望包来验证 .csv 文件中的列是否只包含整数。

我正在使用的文件在年龄列中只有整数,除了一行有一个“`”字符。这就是我想要的期望。我还在文本编辑器中检查了 .csv 文件,可以确认年龄列中的年龄没有用引号括起来。

但是,期望在 100% 的数据中失败。我认为这是因为 pandas 将列作为对象类型(所以是字符串)读取,因为行不正确。我可以使用类似的东西.astype(int)对其进行预处理,因为它会在该行上失败。并且包裹.astype(int)在一个try块中将完全违背为此使用巨大期望的目的。

这是一个最小的工作示例:

好.csv:

age,name
34,Fred
22,Bob
54,Mary

坏的.csv:

age,name
34,Fred
`,Bob
54,Mary

代码:

import great_expectations as ge

df = ge.read_csv("./good.csv");
my_df.expect_column_values_to_be_of_type('age','int')

df = ge.read_csv("./bad.csv");
my_df.expect_column_values_to_be_of_type('age','int')

第一种情况返回

{'success': True,
 'result': {'element_count': 3,
  'missing_count': 0,
  'missing_percent': 0.0,
  'unexpected_count': 0,
  'unexpected_percent': 0.0,
  'unexpected_percent_nonmissing': 0.0,
  'partial_unexpected_list': []}}

所以所有年龄都是整数,它在每一行都成功。我预计第二种情况会失败,但只会在第二行。但是它在所有行上都失败了:

{'success': False,
 'result': {'element_count': 3,
  'missing_count': 0,
  'missing_percent': 0.0,
  'unexpected_count': 3,
  'unexpected_percent': 1.0,
  'unexpected_percent_nonmissing': 1.0,
  'partial_unexpected_list': ['34', '`', '54']}}

所以我想我期待这样的事情:

{'success': False,
 'result': {'element_count': 3,
  'missing_count': 0,
  'missing_percent': 0.0,
  'unexpected_count': 1,
  'unexpected_percent': 0.33,
  'unexpected_percent_nonmissing': 1.0,
  'partial_unexpected_list': ['`']}}

有什么我做错了,还是包裹不能做到这一点?

4

4 回答 4

3

这似乎是一个已知但尚未解决的错误(截至 2018 年 9 月):

https://github.com/great-expectations/great_expectations/issues/110

开发人员正在积极致力于改善行为:

  1. expect_column_values_to_be_of_type(当前期望)已被清理,现在更接近我们认为人们的期望,我们计划将其重命名为 expect_column_values_to_be_stored_as_type

  2. 我们计划引入一个新的期望expect_column_values_to_be_parseasble_as_type,它接受:string、float、int、bool(其他?)并专注于对类型的更语义上有意义的理解(即如果一个值是一个字符串但字符串是“1.0”那么它将传递字符串、浮点数和整数)。

并希望很快会有结果:

1 和 2 的实施即将开始,但我们仍然对建议持开放态度......

于 2018-10-31T13:51:55.917 回答
2

问题是您的值实际上不是整数,它们是字符串。当您使用它读取 csv 时,great_expectations.read_csv()pandas.read_csv()会在内部使用,这将默认您age column的字符串中的数据,因为´.

该方法expect_column_values_to_be_of_type()是非常基本的意思,它只会检查您的值是否是您正在寻找的类型(isinstance()),而不是“可能”是那种类型。

于 2018-10-31T13:53:26.817 回答
1

作为expect_column_values_to_be_parseasble_as_type实现新版本之前的解决方法,我可以使用正则表达式期望来实现相同的结果:

my_df = ge.read_csv("bad.csv")
pattern = r'^\d+$'
result  = my_df.expect_column_values_to_match_regex('age',
                                                    pattern,
                                                    result_format={'result_format': 'COMPLETE'})

result
# In my case I'm only interested in where it went wrong
# print(result['result']['unexpected_list'])
# print(result['result']['unexpected_index_list'])

这使:

{'success': False,
 'result': {'element_count': 3,
  'missing_count': 0,
  'missing_percent': 0.0,
  'unexpected_count': 1,
  'unexpected_percent': 0.3333333333333333,
  'unexpected_percent_nonmissing': 0.3333333333333333,
  'partial_unexpected_list': ['`'],
  'partial_unexpected_index_list': [1],
  'partial_unexpected_counts': [{'value': '`', 'count': 1}],
  'unexpected_list': ['`'],
  'unexpected_index_list': [1]}}

请注意,如果要允许前导 + 或 - 您需要将模式更改为:

pattern = r'^[+-]?\d+$'
于 2018-11-02T13:47:31.947 回答
0

我不知道great_expectations,但你可以在熊猫中简单地使用这个来解决这个问题,

print df[pd.to_numeric(df['age'].fillna(0),errors='coercs').isnull()]['age'].tolist()

输出好.csv

[]

bad.csv 的输出

['`']
于 2018-10-31T13:47:44.223 回答