【问题标题】:Generate random data for testing a pandas dataframe with hypothesis生成随机数据以测试带有假设的 pandas 数据框
【发布时间】:2021-01-13 17:56:41
【问题描述】:

我正在处理很多 pandas 数据帧,我想使用 pytest 对其进行测试,并且我正在使用假设来生成测试数据。

我遇到的问题是它在每一列中生成相同的数据值。

我其实不知道如何生成真实数据来测试..

这是我正在尝试的:

from hypothesis.extra.pandas import data_frames , column, range_indexes
from hypothesis import given, settings, strategies as st
import pandas as pd
from datetime import datetime

data = data_frames(columns=[column(name='key',  elements=st.floats(allow_nan=True)),
                                          column(name='fbms_start_date', elements=st.datetimes(min_value=datetime(2020, 7, 1),
                                                                                               max_value=datetime.now())),
                                          column(name='breakdown_type', elements=st.just("Total")),
                                          column(name='breakdown_one', elements=st.just(float('nan'))),
                                          column(name='adset_id', elements=st.floats(allow_nan=True)),
                                          column(name='adset_name', elements=st.text()),
                                          column(name='campaign_id', elements=st.floats(allow_nan=True, )),
                                          column(name='campaign_name', elements=st.text()),
                                          column(name='reach', elements=st.text()),
                                          column(name='impressions', elements=st.just(float('nan'))),
                                          column(name='spend', elements=st.floats(allow_nan=False)),
                                          column(name='page_likes', elements=st.floats(allow_nan=False)),
                                          column(name='post_engagement', elements=st.sampled_from(['LINK_CLICKS', 
                                                                                                        'POST_ENGAGEMENT', 
                                                                                                        'PAGE_LIKES'])),
                                          column(name='objective', elements=st.floats(allow_nan=False)),
                                          column(name='ads_run', elements=st.sampled_from([True, False]))],
                                          index=range_indexes(min_size=100)
                                        ) 

@given(df=data)
@settings(max_examples=5)
def test_hyothesis(df):
    print(df)
    assert 1

这总是生成以下数据集

key fbms_start_date breakdown_type  breakdown_one   adset_id    adset_name  campaign_id campaign_name   reach   impressions spend   page_likes  post_engagement objective   ads_run
0   0.0 2020-07-01  Total       0.0     0.0             0.0 0.0 LINK_CLICKS 0.0 True
1   0.0 2020-07-01  Total       0.0     0.0             0.0 0.0 LINK_CLICKS 0.0 True
2   0.0 2020-07-01  Total       0.0     0.0             0.0 0.0 LINK_CLICKS 0.0 True
3   0.0 2020-07-01  Total       0.0     0.0             0.0 0.0 LINK_CLICKS 0.0 True
4   0.0 2020-07-01  Total       0.0     0.0             0.0 0.0 LINK_CLICKS 0.0 True
5   0.0 2020-07-01  Total       0.0     0.0             0.0 0.0 LINK_CLICKS 0.0 True
6   0.0 2020-07-01  Total       0.0     0.0             0.0 0.0 LINK_CLICKS 0.0 True
7   0.0 2020-07-01  Total       0.0     0.0             0.0 0.0 LINK_CLICKS 0.0 True
8   0.0 2020-07-01  Total       0.0     0.0             0.0 0.0 LINK_CLICKS 0.0 True
9   0.0 2020-07-01  Total       0.0     0.0             0.0 0.0 LINK_CLICKS 0.0 True

正如您所看到的,每个列都有一个值而不是唯一值,我不知道如何生成可以用来测试的真实值..

任何帮助都会有所帮助...

【问题讨论】:

  • 感谢您的评论,我想过,但问题是这些日期不应该是唯一的

标签: python pandas python-hypothesis


【解决方案1】:

第一个示例是因为假设总是从生成最简单的可能示例开始,这将是全零(等等)。我建议打开 max_examples 设置 - 默认 100 很好,但小于 20非常非常很少。

您还为索引指定了一个非常大的min_size=100 - 真的不可能有一个行数较少的失败示例吗?如果不是,请将其设置得更小 - 假设可以很好地发现具有少量输入的错误,而且它们的生成速度也更快。

完成我们的一组原因后,Hypothesis 会为每一列生成带有“填充值”的数据框 - 在如此大的尺寸和少数示例中,当您只看到前几行和最后几行时,您所看到的只是最小填充值。设置min_size=1,这个问题就会完全消失。

【讨论】:

  • 感谢@zac .. 我想我得到了我所缺少的让我实现它,我会告诉你它是怎么回事
【解决方案2】:

Zac 在his answer 中提供了一些很好的见解,由此,我明白了为什么我会遇到这个问题,我设法用我与文档中的一些 hack 共享的代码获得了一些数据。虽然它没有产生我想要的 100% 的结果,但对于测试来说已经足够了。

这是我如何生成列和之后的数据。

我使用以下代码来定义列策略:

from hypothesis.extra.pandas import data_frames , column, range_indexes
from hypothesis import strategies as st, given, settings
import pandas as pd
from datetime import datetime

datetime_st = st.dates(
    min_value=datetime(2020, 7, 1).date(),
    max_value=datetime.today().date()
)


float_without_nan_st = st.floats(min_value=0.0001, max_value=3030, allow_nan=False)
float_with_nan_st = st.floats(allow_nan=True, allow_infinity=False)
text_st = st.text(alphabet="espoiristusingacolemakeyboard", min_size=5)
boolean_st = st.boolean()

然后我创建了数据框:

df_columns = {
    "fbms_start_date": {"elements": datetime_st, "unique": True},
    "fbmb_spend": {"elements": float_without_nan_st, "unique":True},
    "fbmb_adset_id": {"elements": float_with_nan_st, "unique":False, "fill": st.nothing()},
    "fbmb_adset_name": {"elements": text_st, "unique":False, "fill": st.nothing()}, 
    "fbmb_ads_run": {"elements": boolean_st},
    "fbms_key" : {"elements": float_with_nan_st, "unique":False, "fill": st.nothing()},
    "fbmb_breakdown_type": {"elements": st.just("Total")},
    "fbmb_breakdown_one": {"elements": st.just(float('nan')) }, 
    "fbmb_campaign_id": {"elements": float_with_nan_st, "unique":False, "fill": st.nothing()},
    "fbmb_campaign_name" : {"elements": text_st, "unique":False, "fill": st.nothing()},
    "fbmb_reach" : {"elements": text_st, "unique":False, "fill": st.nothing()},
    "fbmb_impressions" : {"elements": st.integers(min_value=0, max_value=100001) },
    "fbmb_spend" : {"elements": float_with_nan_st, "unique":False, "fill": st.nothing()},
    "fbmb_page_likes" : {"elements": float_with_nan_st, "unique":False, "fill": st.nothing()},
    "fbmb_post_engagement" : {"elements": st.sampled_from(['LINK_CLICKS', 
                                                            'POST_ENGAGEMENT', 
                                                            'PAGE_LIKES']), "unique":False},
    "fbmb_objective" : {"elements": float_with_nan_st, "unique":False, "fill": st.nothing()},
}

接下来我生成了我的数据集:

test_dfs = data_frames(
    index=range_indexes(min_size=10),
    columns=[column(key, **value) for key, value in df_columns.items()],
)

最后,我能够运行以下测试

@given(df=test_dfs)
@settings(max_examples=5)
def test_hyothesis(df):
    print(df)
    assert 1

注意数据集生成索引中的 min_size 和设置中的 max_example。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 2015-01-22
    相关资源
    最近更新 更多