Python-假设:指定和管理 NaN 值
Python-Hypothesis: specifying and managing NaN values
我正在尝试使用 Hypothesis 生成一组我将合并在一起的数据帧。我希望允许每个单独的列具有 NaN 值,并且我希望允许 Hypothesis 生成一些古怪的示例。
但我主要想关注每个数据框中至少有一行具有实际值的示例 - 特别是,我希望能够生成具有在相应列之间共享的一些信息的数据框,例如合并的数据框不为空。 (例如,我希望 store.csv 中 'store' 的某些值与 train.csv 中 'store' 的值重叠。)
我有一些示例代码 here 可以在各处生成 NaN 值和古怪的示例,但大多数生成的示例包含非常少的非 NaN 值。 (数据帧策略从第 57 行开始。)
关于如何创建更多 'realistic' 示例的任何建议?谢谢!
回答我自己的问题,但我很想听听其他答案。
我最后做了两件事:
1) 要求终端用户不给垃圾文件。 (仅仅因为我们有一个神奇的 属性 生成框架并不能免除我们拥有常识的责任,我忘记了这一点。)
2) 通过要求每个数据帧至少有一行没有 NaN 来测试合理事故但不是绝对垃圾的事情。根据该要求,我生成了非 NaN 数据帧,然后添加了一些 NaN。
从那里,ipython 和 .example() 可以很容易地看到发生了什么。
下面的示例代码(google_files 和 google_weeks 是之前创建的自定义策略)
# Create dataframes from the strategies above
# We'll create dataframes with all non-NaN values, then add NaNs to rows
# after the fact
df = draw(data_frames([
column('file', elements=google_files),
column('week', elements=google_weeks),
column('trend',
elements=(integers(min_value=0, max_value=100)))],
index=range_indexes(min_size=1, max_size=100)))
# Add the nans
# With other dataframes, this ended up getting written into a function
rows = len(df)
df.loc[rows+1] = [np.NaN, '2014-01-05 - 2014-01-11', 42]
df.loc[rows+2] = ['DE_BE', np.NaN, 42]
df.loc[rows+3] = ['DE_BE', '2014-01-05 - 2014-01-11', np.NaN]
df.loc[rows+4] = [np.NaN, np.NaN, np.NaN]
我觉得你的解决方案不错,但这里还有两个可能有用的策略:
将 fill=st.nothing()
参数用于 columns
和 series
,以禁用填充行为。这使得条目密集而不是稀疏(ish),因此运行时成本很高,但示例密度发生了显着变化。或者 fill=st.floats(allow_nan=False)
可能更便宜并且仍然有效!
在策略上使用 .filter(...)
来拒绝没有任何 nan-free 行的数据帧。一个典型的经验法则是避免使用 .filter
当它会拒绝超过一半的例子并在超过十分之一时寻找替代方案......但这可以很容易地与第一点结合起来。
我正在尝试使用 Hypothesis 生成一组我将合并在一起的数据帧。我希望允许每个单独的列具有 NaN 值,并且我希望允许 Hypothesis 生成一些古怪的示例。
但我主要想关注每个数据框中至少有一行具有实际值的示例 - 特别是,我希望能够生成具有在相应列之间共享的一些信息的数据框,例如合并的数据框不为空。 (例如,我希望 store.csv 中 'store' 的某些值与 train.csv 中 'store' 的值重叠。)
我有一些示例代码 here 可以在各处生成 NaN 值和古怪的示例,但大多数生成的示例包含非常少的非 NaN 值。 (数据帧策略从第 57 行开始。)
关于如何创建更多 'realistic' 示例的任何建议?谢谢!
回答我自己的问题,但我很想听听其他答案。
我最后做了两件事:
1) 要求终端用户不给垃圾文件。 (仅仅因为我们有一个神奇的 属性 生成框架并不能免除我们拥有常识的责任,我忘记了这一点。)
2) 通过要求每个数据帧至少有一行没有 NaN 来测试合理事故但不是绝对垃圾的事情。根据该要求,我生成了非 NaN 数据帧,然后添加了一些 NaN。
从那里,ipython 和 .example() 可以很容易地看到发生了什么。
下面的示例代码(google_files 和 google_weeks 是之前创建的自定义策略)
# Create dataframes from the strategies above
# We'll create dataframes with all non-NaN values, then add NaNs to rows
# after the fact
df = draw(data_frames([
column('file', elements=google_files),
column('week', elements=google_weeks),
column('trend',
elements=(integers(min_value=0, max_value=100)))],
index=range_indexes(min_size=1, max_size=100)))
# Add the nans
# With other dataframes, this ended up getting written into a function
rows = len(df)
df.loc[rows+1] = [np.NaN, '2014-01-05 - 2014-01-11', 42]
df.loc[rows+2] = ['DE_BE', np.NaN, 42]
df.loc[rows+3] = ['DE_BE', '2014-01-05 - 2014-01-11', np.NaN]
df.loc[rows+4] = [np.NaN, np.NaN, np.NaN]
我觉得你的解决方案不错,但这里还有两个可能有用的策略:
将
fill=st.nothing()
参数用于columns
和series
,以禁用填充行为。这使得条目密集而不是稀疏(ish),因此运行时成本很高,但示例密度发生了显着变化。或者fill=st.floats(allow_nan=False)
可能更便宜并且仍然有效!在策略上使用
.filter(...)
来拒绝没有任何 nan-free 行的数据帧。一个典型的经验法则是避免使用.filter
当它会拒绝超过一半的例子并在超过十分之一时寻找替代方案......但这可以很容易地与第一点结合起来。