使用python在数组中拆分元素

时间:2016-07-30 14:06:40

标签: python arrays numpy

我有一个大阵列,其中一部分如下所示。在每个列表中,第一个数字是开始,第二个数字是结束(所以有一个范围)。我想做的是:

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中做到这一点吗?

感谢

4 个答案:

答案 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运算会更快(即在编译代码中进行迭代)。因此我建议使用布尔掩码。