Транспонирование вектора с использованием numpy
У меня проблема с Ipython - Numpy. Я хочу сделать следующую операцию:
x^T.x
с x, принадлежащим R^n, и x^T - операция транспонирования для вектора x. x извлекается из txt-файла с помощью инструкции:
x = np.loadtxt('myfile.txt')
Проблема в том, что если я использую функцию транспонирования
np.transpose(x)
и использует функцию shape, чтобы узнать размер x, я получаю одинаковые размеры для x и x^T. Numpy дает размер с индексом в верхнем регистре L после каждого измерения. например
print x.shape
print np.transpose(x).shape
(3L, 5L)
(3L, 5L)
Кто-нибудь знает, как решить эту проблему и вычислить x^Tx как матричный продукт?
Спасибо!
7 ответов
Как объясняли другие, транспонирование не будет "работать" так, как вы хотите, для 1D-массивов. Вы можете использовать np.atleast_2d
иметь согласованное определение скалярного произведения:
def vprod(x):
y = np.atleast_2d(x)
return np.dot(y.T, y)
Какие np.transpose
делает это перевернуть кортеж формы, т.е. вы передаете ему массив формы (m, n)
, он возвращает массив формы (n, m)
корми его массивом форм (n,)
... и он возвращает вам тот же массив с формой(n,)
,
Что вы неявно ожидаете, так это чтобы numy принял ваш 1D вектор как 2D массив формы (1, n)
, который будет перенесен в (n, 1)
вектор. Numpy не будет делать это самостоятельно, но вы можете сказать, что это то, что вы хотите, например:
>>> a = np.arange(4)
>>> a
array([0, 1, 2, 3])
>>> a.T
array([0, 1, 2, 3])
>>> a[np.newaxis, :].T
array([[0],
[1],
[2],
[3]])
У меня была такая же проблема, я использовал матрицу numpy для ее решения:
# assuming x is a list or a numpy 1d-array
>>> x = [1,2,3,4,5]
# convert it to a numpy matrix
>>> x = np.matrix(x)
>>> x
matrix([[1, 2, 3, 4, 5]])
# take the transpose of x
>>> x.T
matrix([[1],
[2],
[3],
[4],
[5]])
# use * for the matrix product
>>> x*x.T
matrix([[55]])
>>> (x*x.T)[0,0]
55
>>> x.T*x
matrix([[ 1, 2, 3, 4, 5],
[ 2, 4, 6, 8, 10],
[ 3, 6, 9, 12, 15],
[ 4, 8, 12, 16, 20],
[ 5, 10, 15, 20, 25]])
Хотя использование пустых матриц может быть не лучшим способом представления ваших данных с точки зрения кодирования, очень хорошо, если вы собираетесь выполнять множество матричных операций!
Это либо внутреннее, либо внешнее произведение двух векторов, в зависимости от ориентации, которую вы им назначаете. Вот как рассчитать либо без изменения x
,
import numpy
x = numpy.array([1, 2, 3])
inner = x.dot(x)
outer = numpy.outer(x, x)
Для начинающих L
просто означает, что тип является длинным int. Это не должно быть проблемой. Вам придется предоставить дополнительную информацию о вашей проблеме, поскольку я не могу воспроизвести ее с помощью простого контрольного примера:
In [1]: import numpy as np
In [2]: a = np.arange(12).reshape((4,3))
In [3]: a
Out[3]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
In [4]: a.T #same as np.transpose(a)
Out[4]:
array([[ 0, 3, 6, 9],
[ 1, 4, 7, 10],
[ 2, 5, 8, 11]])
In [5]: a.shape
Out[5]: (4, 3)
In [6]: np.transpose(a).shape
Out[6]: (3, 4)
Вероятно, в вашем конкретном случае происходит что-то неуловимое, что вызывает проблемы. Можете ли вы опубликовать содержимое файла, который вы читаете в x
?
Файл 'myfile.txt' содержит такие строки, как
5.100000 3.500000 1.400000 0.200000 1
4.900000 3.000000 1.400000 0.200000 1
Вот код, который я запускаю:
import numpy as np
data = np.loadtxt('iris.txt')
x = data[1,:]
print x.shape
print np.transpose(x).shape
print x*np.transpose(x)
print np.transpose(x)*x
И я получаю в результате
(5L,)
(5L,)
[ 24.01 9. 1.96 0.04 1. ]
[ 24.01 9. 1.96 0.04 1. ]
Я ожидал бы, что одним из двух последних результатов будет скаляр вместо вектора, потому что x^Tx (или xx^T) должен дать скаляр.
b = np.array([1, 2, 2])
print(b)
print(np.transpose([b]))
print("rows, cols: ", b.shape)
print("rows, cols: ", np.transpose([b]).shape)
Результаты в
[1 2 2]
[[1]
[2]
[2]]
rows, cols: (3,)
rows, cols: (3, 1)
Здесь (3,) можно представить как "(3, 0)". Однако, если вы хотите транспонировать матрицу A, np.transpose(A) является решением. Вкратце, [] преобразует вектор в матрицу, матрица в тензор более высокой размерности.