高效的numpy分组

时间:2019-04-21 10:49:12

标签: python numpy

我有大约10 6 对的列表,其中对中的每个元素都是-1、0或1:

[
 [ 0,  1],
 [-1, -1],
 [ 0, -1],
 [ 1,  0],
 ...
]

我想根据对的 first 元素是否为-1 1 将这些对分成两组(即对列表)。

有没有办法用numpy有效地做到这一点?

尽管我上面使用了术语和符号,但实际上我对线对的实际类型和线对的“列表”并不了解。使用任何numpy或python数据结构都会导致最有效的解决方案。 (但请不要熊猫。)

编辑:

例如,如果对的初始列表为

[
 [ 0, -1],
 [ 0, -1],
 [ 1, -1],
 [-1, -1],
 [ 1,  0],
 [-1,  1],
 [-1, -1],
 [ 0,  0],
 [ 0,  1],
 [-1,  0]
]

...可接受的结果由两个列表组成

[
 [-1, -1],
 [-1,  1],
 [-1, -1],
 [-1,  0]
]

...和

[
 [ 0, -1],
 [ 0, -1],
 [ 1, -1],
 [ 1,  0],
 [ 0,  0],
 [ 0,  1]
]

最后两个列表保留了元素在原始列表中出现的顺序。这是我的偏爱,但这不是必需的。例如,由

组成的解决方案
[
 [-1, -1],
 [-1, -1],
 [-1,  0],
 [-1,  1]
]

...和

[
 [ 0, -1],
 [ 0, -1],
 [ 0,  0],
 [ 0,  1],
 [ 1, -1],
 [ 1,  0],
]

...也可以接受。


1 换句话说,一组中的所有对在其第一位置应为-1,而另一组中的所有元素在其第一处应为0或1位置。

3 个答案:

答案 0 :(得分:2)

只使用两次条件检查正负是否为

import numpy as np

a = np.array([ [ 0, -1], [ 0, -1], [ 1, -1], [-1, -1], [ 1,  0], 
                    [-1,  1], [-1, -1], [ 0,  0], [ 0,  1], [-1,  0]])

pos = a[a[:, 0]!=-1]
neg = a[a[:, 0]==-1]

print (pos)
# [[ 0 -1]
#  [ 0 -1]
#  [ 1 -1]
#  [ 1  0]
#  [ 0  0]
#  [ 0  1]]

print (neg)
# [[-1 -1]
#  [-1  1]
#  [-1 -1]
#  [-1  0]]

答案 1 :(得分:0)

import numpy as np
a = np.random.randint(-1, 2, size=(10, 2))

print(a)
[[ 0  0]
 [ 1  1]
 [ 1  1]
 [-1 -1]
 [ 0 -1]
 [ 1  1]
 [-1  1]
 [-1  0]
 [ 1 -1]
 [ 1  1]]

minus, zero, one = [np.array([r for r in a if r[0] == c]) for c in [-1, 0, 1]]


print(minus)
[[-1 -1]
 [-1  1]
 [-1  0]]
print(zero)
[[ 0  0]
 [ 0 -1]]
print(one)
[[ 1  1]
 [ 1  1]
 [ 1  1]
 [ 1 -1]
 [ 1  1]]

答案 2 :(得分:-1)

您可以自己动手做! 我看到的唯一效率是生成器或类似的东西,它将以节省计算时间为代价来节省内存

def sanitize(yllp):#yllp: list-like of pair
    y = yield
    yield
    for x in yllp:
        if (x[0] in {0,1} and y != -1) or x[0] == -1 == y:
           yield x 

示例:

L = [
     (-1,1), 
     (0,1), 
     (0,1), 
     (-1,1), 
     (-1,0), 
     (-1,-1), 
     (0,0), 
     (1,0)
    ]

#get list starting by 0 or 1
w=sanitize(L)    
w.next()
w.send(0)
for i in w:print(i)

#get list starting by -1
t=sanitize(L)
t.next()
t.send(-1)
for i in t:print(i)