2016-10-29 6 views
0

я получил Numpy массив, как показано ниже:Сравнить элементы в Numpy массиве 3 строки времени

[[3.4, 87] 
[5.5, 11] 
[22, 3] 
[4, 9.8] 
[41, 11.22] 
[32, 7.6]] 

и я хочу:

  1. сравнить элементы в столбце 2, 3 строки за раз
  2. удалить строку с наибольшим значением в колонке 2, 3 строки за раз

Например, в первых трех строках 3 значения в столбце 2 равны 87, 11 и 3 соответственно, и я хотел бы остаться 11 и 3.

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

[[5.5, 11] 
[22, 3] 
[4, 9.8] 
[32, 7.6]] 

Я новичок в Numpy массив, и, пожалуйста, дайте мне совет для достижения этой цели.

ответ

1
import numpy as np 
x = np.array([[3.4, 87], 
       [5.5, 11], 
       [22, 3], 
       [4, 9.8], 
       [41, 11.22], 
       [32, 7.6]]) 

y = x.reshape(-1,3,2) 
idx = y[..., 1].argmax(axis=1) 
mask = np.arange(3)[None, :] != idx[:, None] 
y = y[mask] 
print(y) 
# This might be helpful for the deleted part of your question 
# y = y.reshape(-1,2,2) 
# z = y[...,1]/y[...,1].sum(axis=1) 
# result = np.dstack([y, z[...,None]]) 

дает

[[ 5.5 11. ] 
[ 22. 3. ] 
[ 4. 9.8] 
[ 32. 7.6]] 

«Группировка тремя» с NumPy может быть сделано путем изменения формы массива, чтобы создать новую ось длины 3 - при условии, что исходное число строк делится от 3:

In [92]: y = x.reshape(-1,3,2); y 
Out[92]: 
array([[[ 3.4 , 87. ], 
     [ 5.5 , 11. ], 
     [ 22. , 3. ]], 

     [[ 4. , 9.8 ], 
     [ 41. , 11.22], 
     [ 32. , 7.6 ]]]) 

In [93]: y.shape 
Out[93]: (2, 3, 2) 
      | | | 
      | | o--- 2 columns in each group 
      | o------ 3 rows in each group 
      o--------- 2 groups 

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

In [94]: idx = y[..., 1].argmax(axis=1); idx 
Out[94]: array([0, 1]) 

array([0, 1]) указывает, что в первой группе 0-я индексированная строка содержит максимум (т. 87), а во второй группе первая проиндексированная строка содержит максимум (т. Е. 11.22).

Далее, мы можем генерировать 2D булево маску выбора, которая Правда, где строки не содержат максимальное значение:

In [95]: mask = np.arange(3)[None, :] != idx[:, None]; mask 
Out[95]: 
array([[False, True, True], 
     [ True, False, True]], dtype=bool) 

In [96]: mask.shape 
Out[96]: (2, 3) 

mask имеет форму (2,3). y имеет форму (2,3,2). Если mask is used to index y как в y[mask], то маска совмещен с первыми двумя осями y, и все значения, где mask является True возвращаются:

In [98]: y[mask] 
Out[98]: 
array([[ 5.5, 11. ], 
     [ 22. , 3. ], 
     [ 4. , 9.8], 
     [ 32. , 7.6]]) 

In [99]: y[mask].shape 
Out[99]: (4, 2) 

Кстати, такое же вычисление может быть сделано с использованием Pandas как это:

import numpy as np 
import pandas as pd 
x = np.array([[3.4, 87], 
       [5.5, 11], 
       [22, 3], 
       [4, 9.8], 
       [41, 11.22], 
       [32, 7.6]]) 

df = pd.DataFrame(x) 
idx = df.groupby(df.index // 3)[1].idxmax() 
# drop the row with the maximum value in each group 
df = df.drop(idx.values, axis=0) 

, который дает DataFrame:

 0  1 
1 5.5 11.0 
2 22.0 3.0 
3 4.0 9.8 
5 32.0 7.6 

Возможно, синтаксис Pandas проще в использовании, но для приведенного выше расчета NumPy работает быстрее.

+0

Благодарим за эффективный ответ и подробное описание, и я думаю, что мне нужно время, чтобы полностью их понять. – Heinz

Смежные вопросы