Подтвердить что ты не робот

Удалить среднее значение из матрицы numpy

У меня есть матрица numpy A, где данные организованы в столбце-вектор-тиге. i.e A[:,0] - это первый вектор данных, A[:,1] - второй и т.д. Я хотел знать, был ли более элегантный способ обнулить среднее из этих данных. В настоящее время я делаю это через цикл for:

mean=A.mean(axis=1)
for k in range(A.shape[1]):
    A[:,k]=A[:,k]-mean

Итак, numpy предоставляет функцию для этого? Или это можно сделать более эффективно другим способом?

4b9b3361

Ответ 1

Как обычно, вы можете сделать это несколькими способами. Каждый из подходов ниже работает, добавляя измерение к вектору mean, делая его массивом размером 4 x 1, а затем вещание NumPy заботится обо всем остальном. Каждый подход создает представление mean, а не глубокую копию. Первый подход (т.е. Использование newaxis), скорее всего, предпочтительнее большинства, но другие методы включены для записи.

В дополнение к приведенным ниже подходам см. также ответ ovgolovin, который использует матрицу NumPy, чтобы избежать необходимости полностью изменить mean.

В приведенных ниже методах мы начинаем с следующего массива кода и примера A.

import numpy as np

A = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
mean = A.mean(axis=1)

Использование numpy.newaxis

>>> A - mean[:, np.newaxis]
array([[-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.]])

Использование None

В документации указано, что None можно использовать вместо newaxis. Это потому, что

>>> np.newaxis is None
True

Следовательно, следующее выполнение задачи.

>>> A - mean[:, None]
array([[-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.]])

Тем не менее, newaxis более ясен и должен быть предпочтительным. Кроме того, можно сделать вывод, что newaxis является более перспективным доказательством. См. Также: Numpy: следует ли использовать newaxis или None?

Использование ndarray.reshape

>>> A - mean.reshape((mean.shape[0]), 1)
array([[-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.]])

Изменение ndarray.shape непосредственно

Вы также можете изменить форму mean напрямую.

>>> mean.shape = (mean.shape[0], 1)
>>> A - mean
array([[-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.]])

Ответ 2

Вы также можете использовать matrix вместо array. Тогда вам не нужно будет изменять форму:

>>> A = np.matrix([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
>>> m = A.mean(axis=1)
>>> A - m
matrix([[-1.,  0.,  1.],
        [-1.,  0.,  1.],
        [-1.,  0.,  1.],
        [-1.,  0.,  1.]])

Ответ 3

Да. pylab.demean:

In [1]: X = scipy.rand(2,3)

In [2]: X.mean(axis=1)
Out[2]: array([ 0.42654669,  0.65216704])

In [3]: Y = pylab.demean(X, axis=1)

In [4]: Y.mean(axis=1)
Out[4]: array([  1.85037171e-17,   0.00000000e+00])

Источник:

In [5]: pylab.demean??
Type:           function
Base Class:     <type 'function'>
String Form:    <function demean at 0x38492a8>
Namespace:      Interactive
File:           /usr/lib/pymodules/python2.7/matplotlib/mlab.py
Definition:     pylab.demean(x, axis=0)
Source:
def demean(x, axis=0):
    "Return x minus its mean along the specified axis"
    x = np.asarray(x)
    if axis == 0 or axis is None or x.ndim <= 1:
        return x - x.mean(axis)
    ind = [slice(None)] * x.ndim
    ind[axis] = np.newaxis
    return x - x.mean(axis)[ind]