6

昨天我需要 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 列表类型可以改为接受混合类型。您可以拥有一个包含整数和字符串的列表,两者都保留它们的类型。我需要的是类似于列表的东西,但以类似矩阵的行为运行。

因此,我必须实现自己的类型。对于内部实现,我有两种选择:包含列表的列表和字典。两种解决方案都有缺点:

  • 列表列表需要仔细同步各种列表的大小。交换两行很容易。交换两列不太容易。删除一行也很容易。
  • 字典(以元组作为键)稍好一些,但您必须定义键的限制(例如,如果您的矩阵是 3x3,则不能插入元素 5,5),并且它们使用起来更复杂、删除或交换列或行。

编辑:澄清。我需要这个功能的具体原因是因为我正在阅读 CSV 文件。从 CSV 文件中收集值(可以是字符串、整数、浮点数)后,我想执行交换、删除、插入和其他类似操作。出于这个原因,我需要一个“矩阵列表”。

我的好奇心是:

  • 您知道提供此服务的 Python 数据类型是否已经存在(可能在“不包含电池”的库中)?
  • 为什么标准库中没有提供这种数据类型?可能是太受限的兴趣?
  • 你会如何解决这个需求?字典、列表或其他更智能的解决方案?
4

6 回答 6

11

如果你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

除了花哨的索引之外,我不知道这对你有什么好处,因为正如 Don 指出的那样,你不能用这个矩阵做数学运算。

于 2009-04-04T01:38:21.347 回答
5

我很好奇你为什么想要这个功能;据我了解,拥有矩阵(在 numpy 中)的原因主要是为了进行线性数学(矩阵变换等)。

我不确定小数和字符串乘积的数学定义是什么。

在内部,您可能希望查看稀疏矩阵实现(http://www.inf.ethz.ch/personal/arbenz/pycon03_contrib.pdf)。有很多方法可以做到这一点(散列、列表、链表),每种方法都有自己的优点和缺点。如果您的矩阵不会有很多空值或零,那么您可以放弃稀疏实现。

于 2009-04-04T01:27:36.567 回答
3

你看过 numpy.recarray 功能吗?

例如这里:http://docs.scipy.org/doc/numpy/reference/generated/numpy.recarray.html

它旨在允许具有混合数据类型的数组。

我不知道数组是否适合您的目的,或者您是否真的需要矩阵 - 我没有使用过 numpy 矩阵。但是如果一个数组足够好,recarray 可能会起作用。

于 2009-04-04T02:37:53.120 回答
2

也许这是一个迟到的答案,但是,为什么不使用pandas呢?

于 2013-11-06T11:49:11.083 回答
1

看看 sympy——它在矩阵的多态性方面做得很好,你可以对 col_swap、col_insert、col_del 等 sympy.matrices.Matrix 对象进行操作......

在 [2] 中:将 sympy 导入为 s
在 [6] 中:将 numpy 导入为 np

在 [11] 中:npM = np.array([[1,2,3.0], [4,4,"abc"]], dtype=object)
在 [12] 中:npM
输出[12]:
 [[1 2 3.0]
 [4 4 abc]]

在 [14] 中:类型(npM[0][0])
出[14]:
在 [15] 中:类型(npM[0][2])
出[15]:
在 [16] 中:类型(npM[1][2])
出[16]:


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


在 [27] 中:类型( M[0,2] )
出[27]:
在[28]中:类型(M[1,2])
出[28]:

在 [29] 中:sym= M[1,2]
在 [32] 中:打印 sym.name
美国广播公司

在 [34] 中:sym.n
出[34]:
在 [40] 中: sym.n(subs={'abc':45} )
输出[40]:45.0000000000000

于 2011-03-20T20:28:20.750 回答
0

您是否考虑过使用 csv 模块来处理 csv 文件?

用于 csv 模块的 Python 文档

于 2009-04-04T11:32:13.367 回答