使用其他列表过滤数组

时间:2014-01-21 23:03:08

标签: python numpy filtering

我有一些具有一些功能和背景的数值数据。 我想删除背景,但我需要先过滤掉这些功能。 我已经用起始和停止X值(而不是索引)表示了一个列表。 我该如何获得这些切片的XY数据?

import numpy as np
# some strange inhomogenous step is used, so numpy slicing may be strange
x = range(0,36)
# starting and stopping x value segments that are probably background
bkg_ranges = [ [5., 15.], [28., 34.] ]

# this filter function doesn't work...
bkg_x = filter(lambda n: (np.logical_and(i[0]<=n, n<=i[1]) for i in bkg_ranges), x)

print 'input=', str(x)
print 'output=', str(bkg_x)

此代码段将输出:

input= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
output= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]

我希望输出为

[5,6,7,8,9,10,11,12,13,14,15,   28,29,30,31,32,33,34]

因为bkg_ranges列表表示沿输入数组的起点和终点(不是索引而是排序的x值)

2 个答案:

答案 0 :(得分:3)

问题在于此部分:

filter(lambda n: (np.logical_and(i[0]<=n, n<=i[1]) for i in bkg_ranges), x)

filter() takes a function and an iterable and applies the function to each part of the iterable

现在,看看上面的内容,我们可以看到函数在为i[0]<=n<=i[1])中的每个值应用bkg_ranges时返回生成器。我们可以通过使用map检查输出来看到这一点:

>>> map(lambda n: (lambda n: (np.logical_and(i[0]<=n, n<=i[1]) for i in bkg_ranges), x)
[<generator object <genexpr> at 0x7f12e1bfed70>, <generator object <genexpr> at 0x7f12e1bfedc0>, <generator object <genexpr> at 0x7f12e1bfee10>... ]

现在,由于这些生成器中的每一个都是的东西,它的真实性。因此,当我将lambda函数应用于数组x时,每个值都有一个真值,因此没有任何过滤掉!

你能做什么呢?

摆脱发电机:

>>> map(lambda n: (all(i[0]<=n<=i[1] for i in bkg_ranges)), x) # I Don't have numpy installed
[False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False...]

全是假的。为什么?因为没有数字在5到15之间,也在28到34之间。

现在好吗?好吧,你不想要一个符合逻辑的,你希望过滤器匹配any(),而不是all()值,所以这应该有效:

>>> filter(lambda n: (any(i[0]<=n<=i[1] for i in bkg_ranges)), x)
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 28, 29, 30, 31, 32, 33, 34]

答案 1 :(得分:2)

这应该有效:

# some strange inhomogenous step is used, so numpy slicing may be strange
x = np.arange(0,36)
# starting and stopping x value segments that are probably background
bkg_ranges = [ [5., 15.], [28., 34.] ]
np.concatenate([np.where((x >= start) & (x <= stop))[0]
                for start, stop in bkg_ranges])