我有一些具有一些功能和背景的数值数据。 我想删除背景,但我需要先过滤掉这些功能。 我已经用起始和停止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值)
答案 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])