【问题标题】:Force numpy to keep a list a list强制 numpy 将列表保留为列表
【发布时间】:2013-03-14 17:14:38
【问题描述】:

x2_Kaxs 是一个 Nx3 numpy 列表数组,这些列表中的元素索引到另一个数组。我想最终得到一个 Nx3 numpy 数组,其中包含这些索引元素的列表。

x2_Kcids = array([ ax2_cid[axs] for axs in x2_Kaxs.flat ], dtype=object)

这会输出一个 (N*3)x1 的 numpy 数组。伟大的。这几乎适用于我想要的。我需要做的就是重塑它。

x2_Kcids.shape = x2_Kaxs.shape

这很有效。x2_Kcids 变成了 Nx3 的 numpy 数组。完美的。

除了x2_Kaxs 中的所有列表之外,它们中只有一个元素。然后它变平 将其转换为 Nx3 整数数组,并且我的代码需要稍后在管道中列出一个列表。

我想出的一个解决方案是附加一个虚拟元素,然后将其弹出,但这非常难看。有更好的吗?

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    您的问题实际上与大小为 1 的列表无关,而与所有大小相同的列表有关。我已经创建了这个虚拟样本:

    ax2_cid = np.random.rand(10)
    shape = (10, 3)
    
    x2_Kaxs = np.empty((10, 3), dtype=object).reshape(-1)
    for j in xrange(x2_Kaxs.size):
        x2_Kaxs[j] = [random.randint(0, 9) for k in xrange(random.randint(1, 5))]
    x2_Kaxs.shape = shape
    
    x2_Kaxs_1 = np.empty((10, 3), dtype=object).reshape(-1)
    for j in xrange(x2_Kaxs.size):
        x2_Kaxs_1[j] = [random.randint(0, 9)]
    x2_Kaxs_1.shape = shape
    
    x2_Kaxs_2 = np.empty((10, 3), dtype=object).reshape(-1)
    for j in xrange(x2_Kaxs_2.size):
        x2_Kaxs_2[j] = [random.randint(0, 9) for k in xrange(2)]
    x2_Kaxs_2.shape = shape
    

    如果我们在这三个上运行您的代码,则返回具有以下形状:

    >>> np.array([ax2_cid[axs] for axs in x2_Kaxs.flat], dtype=object).shape
    (30,)
    >>> np.array([ax2_cid[axs] for axs in x2_Kaxs_1.flat], dtype=object).shape
    (30, 1)
    >>> np.array([ax2_cid[axs] for axs in x2_Kaxs_2.flat], dtype=object).shape
    (30, 2)
    

    所有长度为 2 的列表的情况甚至不会让您重塑为 (n, 3)。问题是,即使使用dtype=object,numpy 也会尽可能地numpify 您的输入,如果所有列表的长度相同,则一直到单个元素。我认为您最好的选择是预先分配您的 x2_Kcids 数组:

    x2_Kcids = np.empty_like(x2_Kaxs).reshape(-1)
    shape = x2_Kaxs.shape
    x2_Kcids[:] = [ax2_cid[axs] for axs in x2_Kaxs.flat]
    x2_Kcids.shape = shape
    

    编辑由于unubtu的答案不再可见,我要从他那里偷东西。上面的代码可以写得更好更紧凑:

    x2_Kcids = np.empty_like(x2_Kaxs)
    x2_Kcids.ravel()[:] = [ax2_cid[axs] for axs in x2_Kaxs.flat]
    

    以上面单项列表为例:

    >>> x2_Kcids_1 = np.empty_like(x2_Kaxs_1).reshape(-1)
    >>> x2_Kcids_1[:] = [ax2_cid[axs] for axs in x2_Kaxs_1.flat]
    >>> x2_Kcids_1.shape = shape
    >>> x2_Kcids_1
    array([[[ 0.37685372], [ 0.95328117], [ 0.63840868]],
           [[ 0.43009678], [ 0.02069558], [ 0.32455781]],
           [[ 0.32455781], [ 0.37685372], [ 0.09777559]],
           [[ 0.09777559], [ 0.37685372], [ 0.32455781]],
           [[ 0.02069558], [ 0.02069558], [ 0.43009678]],
           [[ 0.32455781], [ 0.63840868], [ 0.37685372]],
           [[ 0.63840868], [ 0.43009678], [ 0.25532799]],
           [[ 0.02069558], [ 0.32455781], [ 0.09777559]],
           [[ 0.43009678], [ 0.37685372], [ 0.63840868]],
           [[ 0.02069558], [ 0.17876822], [ 0.17876822]]], dtype=object)
    >>> x2_Kcids_1[0, 0]
    array([ 0.37685372])
    

    【讨论】:

    • @unubtu 自从你删除了你的答案,我在我的答案的编辑中无耻地复制了你的 flattened-array-on-the-left-of-assignment。不过不得不选择.ravel(),因为.flat 给出了奇怪的结果。
    【解决方案2】:

    类似于@Denis:

    if x.ndim == 2:
        x.shape += (1,)
    

    【讨论】:

      猜你喜欢
      • 2023-03-23
      • 2014-08-26
      • 1970-01-01
      • 2011-02-01
      • 2020-03-03
      • 2014-04-01
      • 1970-01-01
      • 2014-07-07
      • 2020-04-05
      相关资源
      最近更新 更多