Эффективная группировка в NumPy - PullRequest
0 голосов
/ 21 апреля 2019

У меня есть список из примерно 10 6 пар, где каждый элемент пары имеет значение -1, 0 или 1:

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

Я хочу разделить эти пары на две группы (то есть списки пар) в зависимости от того, равен ли первый элемент пары -1 или нет 1 .

Есть ли способ сделать это эффективно с NumPy?

Несмотря на терминологию и обозначения, которые я использовал выше, я на самом деле агностик относительно фактических типов пар и «списков» пар. Использование любой структуры данных numpy или python приводит к наиболее эффективному решению. (Но не панды, пожалуйста.)

EDIT:

Например, если начальный список пар равен

[
 [ 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 ]

2 голосов
/ 21 апреля 2019

Как насчет того, чтобы просто использовать условие дважды, чтобы проверить положительные и отрицательные значения как

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]]
0 голосов
/ 21 апреля 2019

ты мож, сделай это сам!Единственная эффективность, которую я вижу, - это генератор или что-то подобное, которое сэкономит память за счет времени вычислений

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)
0 голосов
/ 21 апреля 2019
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]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...