Python假设:指定和管理NaN值

时间:2019-01-30 19:48:58

标签: python-hypothesis

我正在尝试使用假设生成一组将合并在一起的数据框。我希望每个单独的列都具有NaN值,并且我希望允许假设生成一些古怪的示例。

但是我主要想集中在每个数据框中至少有一行具有实际值的示例-特别是,我希望能够生成具有在相应列之间共享的某些信息的数据框。合并的数据框不为空。 (例如,我希望store.csv中“商店”中的某些值与train.csv中“商店”中的值重叠。)

我有一些示例代码here,可在各处生成NaN值和古怪的示例,但是大多数生成的示例都包含很少的非NaN值。 (数据框策略从第57行开始。)

关于如何创建更多“现实”示例的任何建议?谢谢!

2 个答案:

答案 0 :(得分:2)

回答我自己的问题,但我很想听听其他答案。

我最终做了两件事:

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] 

答案 1 :(得分:2)

您的解决方案对我来说看起来不错,但以下另外两种策略可能会有所帮助:

  1. 使用fill=st.nothing()columns的{​​{1}}参数来禁用填充行为。这使条目变得密集而不是稀疏,因此存在大量的运行时成本,但示例密度发生了显着变化。另外,series可能更便宜并且仍然可以使用!

  2. 在策略上使用fill=st.floats(allow_nan=False)拒绝没有无Nan行的数据帧。通常的经验法则是避免使用.filter(...),因为它会拒绝一半以上的示例,而在超过十分之一的情况下寻找替代方案……但是可以很容易地与第一点结合起来。