【问题标题】:NumPy native way to store dictionary of arraysNumPy 存储数组字典的本机方式
【发布时间】:2021-06-21 09:27:38
【问题描述】:

我正在寻找是否有更有效的方法(即使用本机 NumPy 功能)来实现我目前正在做的事情。

我的流程是从数组a开始:

a = np.array([[0,2,0,-1],[-0.2,0,-0.1,0],[0,0,-0.1,0],[0,0,0,0]])

array([[ 0. ,  2. ,  0. , -1. ],
       [-0.2,  0. , -0.1,  0. ],
       [ 0. ,  0. , -0.1,  0. ],
       [ 0. ,  0. ,  0. ,  0. ]])

然后我根据值不等于0 的位置进行过滤:

r_indices, c_indicies = np.where(a != 0)

(array([0, 0, 1, 1, 2]), array([1, 3, 0, 2, 2]))

从那里,我创建了一个 Python 字典 b,如下所示:

b = {i: c_indices[r_indices == i] for i in np.unique(r_indices)}

{
    0: array([1, 3]),
    1: array([0, 2]),
    2: array([2])},
}

我这样做是因为我想知道对于给定的唯一行索引r,哪些列索引不是 0

我自己的偏好是尽可能多地尝试使用 NumPy 以利用速度优势。但是,我不确定如何在 NumPy 中构造它,因为字典中的值的长度范围可以从 0(没有值不为零)到 4(所有值都不为零)。

我是否对潜在的速度优势感到偏执?

【问题讨论】:

  • 1) 担心速度优势就是用你的时间换取计算机的时间,只有你自己才能决定你更关心谁的时间。 2)您似乎将汇总统计信息存储在一个 numpy 数组中,通常只有几个元素的 numpy 数组不会提供速度优势。 3) 顺便说一句,这可能与您无关,当您使用浮点数时,我会担心像 where(a != 0) 这样的行,因为它不会匹配不等于但非常接近于零的值。
  • {r:np.nonzero(a[r]) for r in range(4)} 可能更简单,甚至更快。整个数组上的nonzero 更快,但是将其分成行并制作字典基本上是一项 Python 任务。在收集大小不同的数组列表或字典时,即使不是不可能,也很难使用整个数组方法。

标签: python arrays numpy dictionary


【解决方案1】:

您可以通过以下方式使用Pandas

import pandas as pd
import numpy as np

if __name__=='__main__':
    a = np.array([[0, 2, 0, -1], [-0.2, 0, -0.1, 0], [0, 0, -0.1, 0], [0, 0, 0, 0]])
    rows, cols = np.where(a !=0)
    x = list(zip(rows, cols))
    df = pd.DataFrame.from_records(data=x)
    l = df.groupby(0)[1].apply(list)
    L = [np.array(a) for a in l.values]
    d = dict(zip(np.unique(rows), L))

输出

{0: array([1, 3]), 1: array([0, 2]), 2: array([2])}

由于 pandas 在后台使用 numpy,此代码将比常规列表理解更有效。

此外,如果您只需要一个类似字典的对象 - 您可以通过使用 l Pandas.GroupBy 来进一步提高性能:

l.loc[0]

这将导致:

[1, 3]

相当于您示例中的b[0]

并完全省略最后两行,因为Pandas 提供了一种非常快速的机制来处理大量表格数据,如果它们用于相同的事情,通常比普通的dict 对象更可取。

干杯。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-15
    • 1970-01-01
    • 2018-11-03
    • 2016-01-08
    • 2020-10-12
    • 1970-01-01
    • 2016-10-23
    • 2014-05-18
    相关资源
    最近更新 更多