Матрицы в Python - PullRequest
       29

Матрицы в Python

6 голосов
/ 04 апреля 2009

Вчера у меня была потребность в матричном типе в Python.

По-видимому, тривиальным ответом на эту потребность было бы использование numpy.matrix(), но у меня есть еще одна проблема: я хотел бы, чтобы матрица хранила произвольные значения со смешанными типами, подобно списку. numpy.matrix не выполняет этого. Примером является

>>> numpy.matrix([[1,2,3],[4,"5",6]])
matrix([['1', '2', '3'],
        ['4', '5', '6']], 
       dtype='|S4')
>>> numpy.matrix([[1,2,3],[4,5,6]])
matrix([[1, 2, 3],
        [4, 5, 6]])

Как видите, numpy.matrix должен быть однородным по содержанию. Если в моей инициализации присутствует строковое значение, каждое значение неявно сохраняется как строка. Это также подтверждается доступом к отдельным значениям

>>> numpy.matrix([[1,2,3],[4,"5",6]])[1,1]
'5'
>>> numpy.matrix([[1,2,3],[4,"5",6]])[1,2]
'6'

Теперь тип списка Python может принимать смешанные типы. Вы можете иметь список, содержащий целое число и строку, сохраняя их тип. То, что мне нужно, это что-то похожее на список, но работает как матрица.

Поэтому я должен был реализовать свой собственный тип. У меня было два варианта внутренней реализации: список, содержащий списки, и словари. Оба решения имеют недостатки:

  • список списков требует тщательной синхронизации размеров различных списков. Поменять местами два ряда легко. Менять местами два столбца не так просто. Удаление строки также легко.
  • словари (с кортежем в качестве ключа) немного лучше, но вы должны определить пределы вашего ключа (например, вы не можете вставить элемент 5,5, если ваша матрица 3x3), и они более сложны для используется для вставки, удаления или замены столбцов или строк.

Редактировать: уточнение. Конкретная причина, по которой мне нужна эта функциональность, заключается в том, что я читаю файлы CSV. После того, как я соберу значения из файла CSV (значения, которые могут быть строковыми, целыми числами, числами с плавающей запятой), я хотел бы выполнять подкачку, удаление, вставку и другие операции. По этой причине мне нужен «список матриц».

Мое любопытство:

  • Знаете ли вы, если тип данных Python, обеспечивающий эту услугу, уже существует (может быть, в библиотеке "без батареи")?
  • почему этот тип данных не предоставляется в стандартной библиотеке? Возможно, слишком ограниченный интерес?
  • Как бы вы решили эту потребность? Словарь, список или другое разумное решение?

Ответы [ 6 ]

11 голосов
/ 04 апреля 2009

Вы можете иметь неоднородные типы, если ваш dtype равен object:

In [1]: m = numpy.matrix([[1, 2, 3], [4, '5', 6]], dtype=numpy.object)
In [2]: m
Out[2]: 
matrix([[1, 2, 3],
        [4, 5, 6]], dtype=object)
In [3]: m[1, 1]
Out[3]: '5'
In [4]: m[1, 2]
Out[4]: 6

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

5 голосов
/ 04 апреля 2009

Мне любопытно, почему вы хотите эту функциональность; насколько я понимаю, причина наличия матриц (в numpy), прежде всего, заключается в выполнении линейной математики (матричные преобразования и т. д.).

Я не уверен, какое будет математическое определение для произведения десятичной дроби и строки.

Внутренне вы, вероятно, захотите взглянуть на реализации с разреженной матрицей (http://www.inf.ethz.ch/personal/arbenz/pycon03_contrib.pdf).) Существует множество способов сделать это (хэш, список, связанный список), и у каждого есть свои преимущества и недостатки. ваша матрица не будет иметь много нулей или нулей, тогда вы можете отказаться от разреженных реализаций.

3 голосов
/ 04 апреля 2009

Вы смотрели на возможности numpy.recarray?

Например, здесь: http://docs.scipy.org/doc/numpy/reference/generated/numpy.recarray.html

Он предназначен для использования массивов со смешанными типами данных.

Я не знаю, подойдет ли массив вашим целям, или вам действительно нужна матрица - я не работал с матрицей с кучей. Но если массив достаточно хорош, повторный массив может работать.

2 голосов
/ 06 ноября 2013

Может быть, это поздний ответ, но, почему бы не использовать панд ?

1 голос
/ 20 марта 2011

Проверьте sympy - он неплохо справляется с полиморфизмом в его матрицах и у вас есть операции на sympy.matrices.Matrix объекты, такие как col_swap, col_insert, col_del и т. д ...

In [2]: import sympy as s 
In [6]: import numpy as np

In [11]: npM = np.array([[1,2,3.0], [4,4,"abc"]], dtype=object)
In [12]: npM
Out[12]: 
 [[1 2 3.0]
 [4 4 abc]]

In [14]: type( npM[0][0] )
Out[14]: 
In [15]: type( npM[0][2] )
Out[15]: 
In [16]: type( npM[1][2] )
Out[16]: 


In [17]: M = s.matrices.Matrix(npM)
In [18]: M
Out[18]: 
⎡1  2  3.0⎤
⎢         ⎥
⎣4  4  abc⎦


In [27]: type( M[0,2] )
Out[27]: 
In [28]: type( M[1,2] )
Out[28]: 

In [29]: sym= M[1,2] 
In [32]: print sym.name
abc

In [34]: sym.n
Out[34]: 
In [40]: sym.n(subs={'abc':45} )
Out[40]: 45.0000000000000

0 голосов
/ 04 апреля 2009

Рассматривали ли вы модуль csv для работы с файлами csv?

Документы Python для модуля CSV

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...