Python matlab-dummyvar的numpy等价

Python matlab-dummyvar的numpy等价,python,numpy,Python,Numpy,为了很好地处理类别变量,matlab的dummyvar函数最类似于Python的是什么 下面是一个说明我的问题的示例,使用NxM矩阵表示将N个数据点划分为的M种不同方式,您可以使用一些广播魔术来快速获得虚拟阵列: >>> partitions = np.array([[1, 1, 2, 2, 1, 2, 2, 2, 1, 1], ... [1, 2, 2, 1, 2, 1, 2, 2, 2, 1], ...

为了很好地处理类别变量,matlab的dummyvar函数最类似于Python的是什么


下面是一个说明我的问题的示例,使用NxM矩阵表示将N个数据点划分为的M种不同方式,您可以使用一些广播魔术来快速获得虚拟阵列:

>>> partitions = np.array([[1, 1, 2, 2, 1, 2, 2, 2, 1, 1],
...                        [1, 2, 2, 1, 2, 1, 2, 2, 2, 1],
...                        [1, 1, 1, 2, 2, 2, 1, 3, 3, 2]])
>>> n = np.max(partitions)
>>> d = (partitions.T[:, None, :] == np.arange(1, n+1)[:, None]).astype(np.int)
>>> d = d.reshape(partitions.shape[1], -1)
>>> d.dot(d.T)
array([[3, 2, 1, 1, 1, 1, 1, 0, 1, 2],
       [2, 3, 2, 0, 2, 0, 2, 1, 2, 1],
       [1, 2, 3, 1, 1, 1, 3, 2, 1, 0],
       [1, 0, 1, 3, 1, 3, 1, 1, 0, 2],
       [1, 2, 1, 1, 3, 1, 1, 1, 2, 2],
       [1, 0, 1, 3, 1, 3, 1, 1, 0, 2],
       [1, 2, 3, 1, 1, 1, 3, 2, 1, 0],
       [0, 1, 2, 1, 1, 1, 2, 3, 2, 0],
       [1, 2, 1, 0, 2, 0, 1, 2, 3, 1],
       [2, 1, 0, 2, 2, 2, 0, 0, 1, 3]])
有一个明显的缺点是,即使一行只有几个不同的值,我们正在创建的虚拟数组也会根据具有最多值的行的需要为该行包含相同数量的列。但是,除非您有巨大的阵列,否则它可能比任何其他方法都要快


如果您想要一个可伸缩的解决方案,那么您需要为虚拟矩阵使用稀疏数组。如果您不熟悉CSR稀疏格式的详细信息,可能很难遵循以下代码:

import scipy.sparse as sps
def sparse_dummyvar(partitions):
    num_rows = np.sum(np.max(partitions, axis=1))
    nnz = np.prod(partitions.shape)
    as_part = np.argsort(partitions, axis=1)
    # You could get s_part from the indices in as_part, left as
    # an exercise for the reader...
    s_part = np.sort(partitions, axis=1)
    mask = np.hstack(([[True]]*len(items_per_row),
                      s_part[:, :-1] != s_part[:, 1:]))
    indptr = np.where(mask.ravel())[0]
    indptr = np.append(indptr, nnz)

    return sps.csr_matrix((np.repeat([1], nnz), as_part.ravel(), indptr),
                          shape=(num_rows, partitions.shape[1],))
这将返回
dummyvar(分区)
的转置。只需调用
csc_矩阵
而不是
csr_矩阵
并交换形状值,即可获得阵列而无需转置。但由于您只在矩阵及其转置的乘积之后,并且scipy在相乘之前将所有内容转换为CSR格式,所以它可能会像这样稍微快一点。您现在可以执行以下操作:

>>> dT = sparse_dummyvar(partitions)
>>> dT.T.dot(dT)
<10x10 sparse matrix of type '<type 'numpy.int32'>'
    with 84 stored elements in Compressed Sparse Column format>
>>> dT.T.dot(dT).A
array([[3, 2, 1, 1, 1, 1, 1, 0, 1, 2],
       [2, 3, 2, 0, 2, 0, 2, 1, 2, 1],
       [1, 2, 3, 1, 1, 1, 3, 2, 1, 0],
       [1, 0, 1, 3, 1, 3, 1, 1, 0, 2],
       [1, 2, 1, 1, 3, 1, 1, 1, 2, 2],
       [1, 0, 1, 3, 1, 3, 1, 1, 0, 2],
       [1, 2, 3, 1, 1, 1, 3, 2, 1, 0],
       [0, 1, 2, 1, 1, 1, 2, 3, 2, 0],
       [1, 2, 1, 0, 2, 0, 1, 2, 3, 1],
       [2, 1, 0, 2, 2, 2, 0, 0, 1, 3]])
dT=sparse\u dummyvar(分区) >>>dT.T.dot(dT) >>>dT.T.dot(dT.A) 数组([[3,2,1,1,1,1,1,1,0,1,2], [2, 3, 2, 0, 2, 0, 2, 1, 2, 1], [1, 2, 3, 1, 1, 1, 3, 2, 1, 0], [1, 0, 1, 3, 1, 3, 1, 1, 0, 2], [1, 2, 1, 1, 3, 1, 1, 1, 2, 2], [1, 0, 1, 3, 1, 3, 1, 1, 0, 2], [1, 2, 3, 1, 1, 1, 3, 2, 1, 0], [0, 1, 2, 1, 1, 1, 2, 3, 2, 0], [1, 2, 1, 0, 2, 0, 1, 2, 3, 1], [2, 1, 0, 2, 2, 2, 0, 0, 1, 3]])
谢谢你的建议。如果可能的话,拥有至少有一个退化分区(其中有许多非常小的类别)的非常大的数组的用例肯定是我应该处理的用例。我已经在OP中添加了更多信息,说明我正在尝试做什么,以及如何告知问题约束。@aestrivex查看编辑,我不认为你可以获得比这更大的可伸缩性,尽管它需要使用scipy的稀疏模块。是的,我认为dummyvar的matlab实现同样利用了稀疏性(有一个关于如何在八度音阶中实现的问题基本上回答了稀疏性问题。我希望scipy或numpy有更直接的东西(即更简单的API),但我想没有)。谢谢!
>>> partitions = np.array([[1, 1, 2, 2, 1, 2, 2, 2, 1, 1],
...                        [1, 2, 2, 1, 2, 1, 2, 2, 2, 1],
...                        [1, 1, 1, 2, 2, 2, 1, 3, 3, 2]])
>>> n = np.max(partitions)
>>> d = (partitions.T[:, None, :] == np.arange(1, n+1)[:, None]).astype(np.int)
>>> d = d.reshape(partitions.shape[1], -1)
>>> d.dot(d.T)
array([[3, 2, 1, 1, 1, 1, 1, 0, 1, 2],
       [2, 3, 2, 0, 2, 0, 2, 1, 2, 1],
       [1, 2, 3, 1, 1, 1, 3, 2, 1, 0],
       [1, 0, 1, 3, 1, 3, 1, 1, 0, 2],
       [1, 2, 1, 1, 3, 1, 1, 1, 2, 2],
       [1, 0, 1, 3, 1, 3, 1, 1, 0, 2],
       [1, 2, 3, 1, 1, 1, 3, 2, 1, 0],
       [0, 1, 2, 1, 1, 1, 2, 3, 2, 0],
       [1, 2, 1, 0, 2, 0, 1, 2, 3, 1],
       [2, 1, 0, 2, 2, 2, 0, 0, 1, 3]])
import scipy.sparse as sps
def sparse_dummyvar(partitions):
    num_rows = np.sum(np.max(partitions, axis=1))
    nnz = np.prod(partitions.shape)
    as_part = np.argsort(partitions, axis=1)
    # You could get s_part from the indices in as_part, left as
    # an exercise for the reader...
    s_part = np.sort(partitions, axis=1)
    mask = np.hstack(([[True]]*len(items_per_row),
                      s_part[:, :-1] != s_part[:, 1:]))
    indptr = np.where(mask.ravel())[0]
    indptr = np.append(indptr, nnz)

    return sps.csr_matrix((np.repeat([1], nnz), as_part.ravel(), indptr),
                          shape=(num_rows, partitions.shape[1],))
>>> dT = sparse_dummyvar(partitions)
>>> dT.T.dot(dT)
<10x10 sparse matrix of type '<type 'numpy.int32'>'
    with 84 stored elements in Compressed Sparse Column format>
>>> dT.T.dot(dT).A
array([[3, 2, 1, 1, 1, 1, 1, 0, 1, 2],
       [2, 3, 2, 0, 2, 0, 2, 1, 2, 1],
       [1, 2, 3, 1, 1, 1, 3, 2, 1, 0],
       [1, 0, 1, 3, 1, 3, 1, 1, 0, 2],
       [1, 2, 1, 1, 3, 1, 1, 1, 2, 2],
       [1, 0, 1, 3, 1, 3, 1, 1, 0, 2],
       [1, 2, 3, 1, 1, 1, 3, 2, 1, 0],
       [0, 1, 2, 1, 1, 1, 2, 3, 2, 0],
       [1, 2, 1, 0, 2, 0, 1, 2, 3, 1],
       [2, 1, 0, 2, 2, 2, 0, 0, 1, 3]])