我有一个大阵列,其中一部分如下所示。在每个列表中,第一个数字是开始,第二个数字是结束(所以有一个范围)。我想做的是:
1: 过滤掉那些小于300的列表(范围)(例如,必须删除以下数组中的第18个列表)
2: 以这种方式获得较小的范围(列表):(开始+ 100)到(开始+ 200)。例如,第一个列表是[569,669]。
我尝试在numpy中使用不同的split函数,但是没有它们给出了我正在寻找的东西。
array([[ 469, 1300],
[ 171, 1440],
[ 187, 1564],
[ 204, 1740],
[ 40, 1363],
[ 56, 1457],
[ 132, 606],
[1175, 2096],
[ 484, 2839],
[ 132, 4572],
[ 166, 1693],
[ 69, 3300],
[ 142, 1003],
[2118, 2118],
[ 715, 1687],
[ 301, 1006],
[ 48, 2142],
[ 63, 330],
[ 479, 2411]], dtype=uint32)
你们知道如何在python中做到这一点吗?
感谢
答案 0 :(得分:2)
假设你的数组被称为A
,那么:
import numpy as np
# Filter out differences not wanted
gt300 = A[(np.diff(A) >= 300).flatten()]
# Set new value of first column
gt300[:,0] += 100
# Set value of second column
gt300[:,1] = gt300[:,0] + 100
或者类似的东西:
B = A[:,0][(np.diff(A) >= 300).flatten()]
C = np.repeat(B, 2).reshape((len(B), 2)) + [100, 200]
答案 1 :(得分:0)
data = [[ 469, 1300],
# ...
[ 63, 330],
[ 479, 2411]]
print(
filter(lambda v: v[1] - v[0] >= 300, data)
)
print(
[[v[0] + 100, v[0] + 200] for v in data]
)
说明:
第一个命令使用内置filter方法根据lambda表达式过滤剩余的元素。
第二个迭代遍历列表并在生成时生成一个新的。
如果输入和输出应该是numpy数组,请尝试以下操作。注意:如果不创建新数组,就无法过滤numpy数组。
data = array([
( 469, 1300),
( 171, 1440),
# ...
( 63, 330),
( 479, 2411)], dtype=(uint32, uint32))
print(
array(filter(lambda v: v[1] - v[0] >= 300, data), dtype=(uint32, uint32))
)
print(
array([[v[0] + 100, v[0] + 200] for v in data], dtype=(uint32, uint32))
)
答案 2 :(得分:0)
之前的一般说明: 您应该使用tuples来代表这些范围,而不是列表。它们是不可变数据类型,对其中的项目顺序具有意义。
对于1,在python中过滤非常容易:
filter(lambda single_range: single_range[1] - single_range[0] > 300, ranges)
更清楚的方式(在我看来)这样做是为了列表理解:
[(start, end) for start, end in ranges if end - start > 300]
对于2,我并不完全明白你的意思,但如果你的意思是创建一个新的范围列表,其中每个范围是使用单个函数进行更改,则表示地图(或我的首选方式,列表)理解是平等但更具描述性的:
[(start + 100, start + 200) for start, end in ranges]
答案 3 :(得分:0)
我们可以找到哪些行与:
的差异很小In [745]: mask=(x[:,1]-x[:,0])<300
In [746]: mask
Out[746]:
array([False, False, False, False, False, False, False, False, False,
False, False, False, False, True, False, False, False, True, False], dtype=bool)
我们可以使用mask
来选择这些行,或取消选择它们
In [747]: x[mask,:]
Out[747]:
array([[2118, 2118],
[ 63, 330]], dtype=uint32)
In [748]: x[~mask,:]
Out[748]:
array([[ 469, 1300],
[ 171, 1440],
[ 187, 1564],
[ 204, 1740],
...
[ 479, 2411]], dtype=uint32)
制作一组新的范围;得到第一列;这里我使用[0]
所以选择仍然是一个列数组:
In [750]: x[:,[0]]
Out[750]:
array([[ 469],
[ 171],
[ 187],
...
[ 48],
[ 63],
[ 479]], dtype=uint32)
添加所需的偏移量。这利用了广播。
In [751]: x[:,[0]]+[100,200]
Out[751]:
array([[ 569, 669],
[ 271, 371],
[ 287, 387],
[ 304, 404],
[ 140, 240],
[ 156, 256],
...
[ 401, 501],
[ 148, 248],
[ 163, 263],
[ 579, 679]], dtype=int64)
还有其他构建这种数组的方法
np.column_stack([x[:,0]+100,x[:,0]+200])
np.array([x[:,0]+100, x[:,0]+200]).T # or vstack
其他答案建议Python
列表filter
。我偏爱在这种用途中列出理解,例如:
In [756]: np.array([i for i in x if (i[1]-i[0])<300])
Out[756]:
array([[2118, 2118],
[ 63, 330]], dtype=uint32)
对于小型列表,纯Python方法往往更快。但是如果对象已经是numpy
数组,则使用同时处理整个数组的numpy
运算会更快(即在编译代码中进行迭代)。因此我建议使用布尔掩码。