【问题标题】:Testing pandas dataframe with unittest framework使用 unittest 框架测试 pandas 数据框
【发布时间】:2021-01-22 06:57:59
【问题描述】:

我正在尝试使用 python unittest 框架进行处理 csv 文件的单元测试。 我想测试列名匹配、列中的值匹配等情况。 我知道有更方便的库,例如 datatestpytest ,但我只能在我的项目中使用 unittest

猜我使用了错误的unittest.TestCase 方法,并以错误的格式发送数据。 请告知如何更好地做到这一点。

db.csv 示例:

  TIMESTAMP   TYPE   VALUE YEAR  FILE   SHEET
0 02-09-2018  Index   45   2018  tq.xls A01
1 13-05-2018  Index   21   2018  tq.xls A01
2 22-01-2019  Index   9    2019  aq.xls B02

这里是代码示例:

import pandas as pd
import unittest

class DFTests(unittest.TestCase):

    def setUp(self):
        test_file_name =  'db.csv'
        try:
            data = pd.read_csv(test_file_name,
                sep = ',',
                header = 0)
        except IOError:
            print('cannot open file')
        self.fixture = data

    #Check column names
    def test_columns(self):
        self.assertEqual(
            self.fixture.columns,
            {'TIMESTAMP', 'TYPE', 'VALUE','YEAR','FILE','SHEET'},
        )

    #Check timestamp format
    def test_timestamp(self):
        self.assertRaisesRegex(
            self.fixture['TIMESTAMP'],
            r'\d{2}-\d{2}-\d{4}'
        )

    #Check year values
    def test_year_values(self):
        self.assertIn(
            self.fixture['YEAR'],
            {2018, 2019, 2020},
        )


if __name__ == '__main__':
    unittest.main()

错误:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
TypeError: assertRaisesRegex() arg 1 must be an exception type or tuple of exception types
TypeError: 'Series' objects are mutable, thus they cannot be hashed

感谢任何帮助。

【问题讨论】:

  • 为了测试一些替代方案,最好有一个您正在处理的 .csv 的代表性 sn-p。
  • @anddt 当然,我添加了示例

标签: python pandas dataframe unit-testing python-unittest


【解决方案1】:

您可以使用列表推导对每个数据框行进行断言。 试试这样的:

import pandas as pd
import unittest

colnames = ["TIMESTAMP", " TYPE", " VALUE", " YEAR", " FILE", " SHEET"]
years = set([2018, 2019, 2020])


class DfTests(unittest.TestCase):
    def setUp(self):
        try:
            data = pd.read_csv("data.csv", sep=",")
            self.fixture = data
        except IOError as e:
            print(e)

    def test_colnames(self):
        self.assertListEqual(list(self.fixture.columns), colnames)

    def test_timestamp_format(self):
        ts = self.fixture["TIMESTAMP"]
        # You need to check for every row in the dataframe
        [self.assertRegex(i, r"\d{2}-\d{2}-\d{4}") for i in ts]

    def test_years(self):
        df_years = self.fixture[" YEAR"]
        self.assertTrue(all([i in years for i in df_years]))


if __name__ == "__main__":
    unittest.main()

另外,请记住pandas 有一些内置的testing 函数。另一方面,当对数据帧(和一般数据验证)进行单元测试时,great_expectations 可能是完成这项工作的最佳工具。

【讨论】:

  • 也许你可以建议,我的 test_timestamp_format 有错误:TypeError: expected string or bytes-like object
  • 奇怪,它在我的机器上对你提供的数据有效。尝试在该列表理解的第一个 i 中使用 str(i)
  • 另外,这样的错误可能表明并非TIMESTAMP 中的所有条目都是字符串。考虑添加一个测试来检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-19
  • 1970-01-01
  • 2015-01-27
  • 2015-03-13
  • 1970-01-01
相关资源
最近更新 更多