你如何单元测试Python DataFrames

时间:2017-01-25 13:19:58

标签: unit-testing pandas numpy dataframe

我如何对python数据帧进行单元测试?

我的函数有输入和输出作为数据帧。几乎我所有的功能都是这样做的。现在,如果我想进行单元测试,那么最好的方法是什么?为每个函数创建一个新的数据框(填充值)似乎有点费力?

您可以转介我的材料吗?你应该为这些功能编写单元测试吗?

7 个答案:

答案 0 :(得分:16)

虽然Pandas的测试功能主要用于内部测试,但NumPy包含一组非常有用的测试功能,这些功能在此处记录:NumPy Test Support

这些函数比较NumPy数组,但您可以使用values属性获取作为Pandas数据框架构的数组。您可以定义一个简单的数据框,并比较函数返回的内容。

您可以使用的一种技术是为许多函数定义一组测试数据。这样,您可以使用Pytest Fixtures一次定义该数据框,并在多个测试中使用它。

在资源方面,我发现Testing with NumPy and Pandas上的这篇文章非常有用。我还在今年的PyCon Canada上做了关于数据分析测试的简短介绍:Automate Your Data Analysis Testing

答案 1 :(得分:5)

您可以使用熊猫测试功能:

以不同的方式将您的结果与计算的结果进行比较将提供更多的灵活性。

例如:

df1=pd.DataFrame({'a':[1,2,3,4,5]})
df2=pd.DataFrame({'a':[6,7,8,9,10]})

expected_res=pd.Series([7,9,11,13,15])
pd.testing.assert_series_equal((df1['a']+df2['a']),expected_res,check_names=False)

有关更多详细信息,请参阅此link

答案 2 :(得分:4)

我不认为为单元测试创​​建小型DataFrame很困难吗?

import pandas as pd
from nose.tools import assert_dict_equal

input = pd.DataFrame.from_dict({
    'field_1': [some, values],
    'field_2': [other, values]
})
expected = {
    'result': [...]
}
assert_dict_equal(expected, my_func(input).to_dict(), "oops, there's a bug...")

答案 3 :(得分:3)

我建议在docstrings中将值写为CSV(如果它们很大,则将它们分开编写)并使用pd.read_csv()解析它们。您也可以解析CSV的预期输出,并进行比较,或者使用df.to_csv()将CSV写出并进行差异化。

答案 4 :(得分:0)

您可以使用snapshottest并执行以下操作:

def test_something_works(snapshot): # snapshot is a pytest fixture from snapshottest
    data_frame = calc_something_and_return_pandas_dataframe()
    snapshot.assert_match(data_frame.to_csv(index=False), 'some_module_level_unique_name_for_the_snapshot')

这将创建一个快照文件夹,其中包含一个文件,其中包含csv输出,您可以在更改代码后使用--snapshot-update更新该文件。

它通过将data_frame变量与保存到磁盘的变量进行比较来工作。

可能值得一提的是,应将快照签入源代码管理。

答案 5 :(得分:0)

frame-fixtures Python程序包(我是我的作者)旨在简化为单元测试或性能测试“创建新数据框(填充值)”的情况。

例如,如果要对带有数字索引的浮点数和字符串的DataFrame进行测试,则可以使用紧凑的字符串声明来生成DataFrame。

StatefulSet

答案 6 :(得分:0)

如果您使用的是 pytest,pandasSnapshot 会很有用。

# use with pytest
import pandas as pd
from snapshottest_ext.dataframe import PandasSnapshot

def test_format(snapshot):
    df = pd.DataFrame([['a', 'b'], ['c', 'd']],
                      columns=['col 1', 'col 2'])
    snapshot.assert_match(PandasSnapshot(df))

一个很大的缺点是快照不再可读。 (将内容存储为 csv 更具可读性,但存在问题。

PS:我是pytest快照扩展的作者。