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