Создать новый массив из массива numpy на основе условий из списка - PullRequest
0 голосов
/ 31 августа 2010

Предположим, у меня есть массив, определенный как:

data = np.array([('a1v1', 'a2v1', 'a3v1', 'a4v1', 'a5v1'),
       ('a1v1', 'a2v1', 'a3v1', 'a4v2', 'a5v1'),
       ('a1v3', 'a2v1', 'a3v1', 'a4v1', 'a5v2'),
       ('a1v2', 'a2v2', 'a3v1', 'a4v1', 'a5v2'),
       ('a1v2', 'a2v3', 'a3v2', 'a4v1', 'a5v2'),
       ('a1v2', 'a2v3', 'a3v2', 'a4v2', 'a5v1'),
       ('a1v3', 'a2v3', 'a3v2', 'a4v2', 'a5v2'),
       ('a1v1', 'a2v2', 'a3v1', 'a4v1', 'a5v1'),
       ('a1v1', 'a2v3', 'a3v2', 'a4v1', 'a5v2'),
       ('a1v2', 'a2v2', 'a3v2', 'a4v1', 'a5v2'),
       ('a1v1', 'a2v2', 'a3v2', 'a4v2', 'a5v2'),
       ('a1v3', 'a2v2', 'a3v1', 'a4v2', 'a5v2'),
       ('a1v3', 'a2v1', 'a3v2', 'a4v1', 'a5v2'),
       ('a1v2', 'a2v2', 'a3v1', 'a4v2', 'a5v1')],
      dtype=[('a1', '|S4'), ('a2', '|S4'), ('a3', '|S4'),
             ('a4', '|S4'), ('a5', '|S4')])

Как создать функцию для вывода списка элементов данных по строкам с условиями, указанными в списке кортежей, r.

r = [('a1', 'a1v1'), ('a4', 'a4v1')]

Я знаю, что это можно сделать вручную следующим образом:

data[(data['a1']=='a1v1') & data['a4']=='a4v1']

Как насчет удаления строк из данных, соответствующих r.

data[(data['a1']!='a1v1') | data['a4']!='a4v1']

Спасибо.

1 Ответ

1 голос
/ 31 августа 2010

Если я вас правильно понимаю, вы хотите перечислить всю строку, где данный набор столбцов равен некоторому значению. В этом случае это должно быть то, что вы хотите, хотя это немного многословно и неясно:

test_cols = data[['a1', 'a4']]
test_vals = np.array(('a1v1', 'a4v1'), test_cols.dtype)
data[test_cols == test_vals]

Обратите внимание на индексацию в стиле "вложенного списка" ... Это самый простой способ выделить несколько столбцов структурированного массива. Например.

data[['a1', 'a4']] 

даст

array([('a1v1', 'a4v1'), ('a1v1', 'a4v2'), ('a1v3', 'a4v1'),
       ('a1v2', 'a4v1'), ('a1v2', 'a4v1'), ('a1v2', 'a4v2'),
       ('a1v3', 'a4v2'), ('a1v1', 'a4v1'), ('a1v1', 'a4v1'),
       ('a1v2', 'a4v1'), ('a1v1', 'a4v2'), ('a1v3', 'a4v2'),
       ('a1v3', 'a4v1'), ('a1v2', 'a4v2')], 
      dtype=[('a1', '|S4'), ('a4', '|S4')])

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

Однако для структурированных массивов dtype должен точно соответствовать. Например. data[['a1', 'a4']] == ('a1v1', 'a4v1') просто дает False, поэтому мы должны создать массив значений, которые мы хотим проверить, используя тот же тип dtype, что и столбцы, с которыми мы проверяем. Таким образом, мы должны сделать что-то вроде:

test_cols = data[['a1', 'a4']]
test_vals = np.array(('a1v1', 'a4v1'), test_cols.dtype)

прежде чем мы сможем сделать это:

data[test_cols == test_vals]

Что дает то, что мы были первоначально после:

array([('a1v1', 'a2v1', 'a3v1', 'a4v1', 'a5v1'),
       ('a1v1', 'a2v2', 'a3v1', 'a4v1', 'a5v1'),
       ('a1v1', 'a2v3', 'a3v2', 'a4v1', 'a5v2')], 
      dtype=[('a1', '|S4'), ('a2', '|S4'), ('a3', '|S4'), ('a4', '|S4'), ('a5', '|S4')])

Надеюсь, в любом случае это имеет смысл ...

...