Python 用compress()过滤,内置的filter()
函数使用谓词来确定对某个数据项的取舍。除了使用函数进行计算,也可以使用第二个可迭代对象确定对元素的取舍。
filter()
函数定义如下:
def filter(function, iterable):
i1, i2 = tee(iterable, 2)
return compress(i1, map(function, i2))
首先用tee()
函数克隆出可迭代对象的两个副本(稍后会详细介绍该函数),map()
函数将谓词函数function()
映射至可迭代对象的每个值,形成由True
和False
组成的布尔值序列,保留其中与True
关联的值,实现对源数据的过滤。这样就基于compress()
函数实现了filter()
函数的效果。
前面使用了一个简单的生成器表达式拣选数据,其关键部分如下:
choose = lambda rule: (x == 0 for x in rule)
keep = [v for v, pick in zip(data, choose(all)) if pick]
规则的每个值都是一个能生成布尔值序列的函数。选择所有值的规则对应全为True
的序列,选择固定子数据集则需要在True
值和 c-1 个False
值间循环。
如果用compress(some_source, choose(rule))
代替上面的列表解析,处理过程可简化为:
compress(data, choose(all))
compress(data, choose(subset))
compress(data, choose(randomized))
这些示例使用了前面定义的拣选规则:all
、subset
和randomized
,其中subset
和randomized
需要定义合适的系数从源数据中取出 \frac{1}{c} 行。choose
表达式基于其中一条拣选规则定义一个布尔值可迭代对象。通过将该行选择可迭代序列应用于源数据来选择行。
以上实现都是非严格的,只在需要时才从数据源中读取行数据,从而高效处理海量数据。另外,简洁的Python代码让我们无须编写复杂的配置文件和解析器,便可以灵活选择拣选规则,用一小段代码就可以完成大型数据取样应用的配置。