python - 映射对角线

标签 python pandas performance numpy vectorization

假设我有以下数据框:

idx = ['H',"A","B","C","D"]
idxp = idx[1:] + [idx[0]]
idxm = [idx[-1]] + idx[:-1]
idx, idxp, idxm
j = np.arange(25).reshape(5,5)
J = pd.DataFrame(j, index=idx, columns=idx)
np.fill_diagonal(J.values, 0)
J

enter image description here

作为输出,我想得到这样的数组:

  • 下面矩阵的下半部分和对角线中到处都有零
  • 矩阵上部的值是通过矩阵 J 对角线上方的数字计算得出的,因此向量 v = [1, 7, 13, 19]。
  • 使用 v,将第一行计算为 v 的累积和: 从头到尾,得到[1,8,21,40]
  • 利用v,计算第二行v从第二个索引到末尾的累加和,得到[7, 20, 39]
  • 等等,直到到达 v 的最后一个索引

换句话说,这将为我们提供以下矩阵:

m_exp = np.array([[0,1,8,21,40],
             [0,0,7,20,39],
             [0,0,0,13,32],
             [0,0,0,0,19],
             [0,0,0,0,0],
             ])

到目前为止,我发现计算该矩阵的最佳方法是使用下面的代码:

travelup = np.array([np.pad(np.cumsum(J.values.diagonal(1)[n:]), (n+1,0), 'constant') for n in range(J.values.shape[0])])

然而,这涉及一个理解列表,实际上我的矩阵要大得多,并且该代码被调用数千次。

有没有办法通过使用映射来转换流程,使其更快,避免循环?

最佳答案

列出了一些方法。

我。基本方法

a = J.values
p = np.r_[0,a.ravel()[1::a.shape[1]+1]] # or np.r_[0,np.diag(a,1)]
n = len(p)
out = np.triu(np.broadcast_to(p,(n,n)),1).cumsum(1)

pn 将在接下来列出的替代方案中重复使用。

A.替代方案#1

或者使用广播乘法来获得最终输出 -

out = (~np.tri(n, dtype=bool)*p).cumsum(1)

B.替代方案#2

或者使用 cumsum 上的 outer-subtraction -

c = p.cumsum()
out = np.triu(c-c[:,None])

C.替代方案#3

或者用np.tri替换np.triu -

out = (c-c[:,None])*~np.tri(n, dtype=bool)

c 将在接下来列出的替代方案中重新使用。

二.使用numexpr

对于大型数组,请通过 numexpr 利用多核。因此,替代方案是 -

import numexpr as ne

out = ne.evaluate('(c-c2D)*M',{'c2D':c[:,None],'M':~np.tri(n, dtype=bool)})

A.替代方案#1

out = ne.evaluate('(c-c2D)*(~M)',{'c2D':c[:,None],'M':np.tri(n, dtype=bool)})

B.替代方案#2

r = np.arange(n)
out = ne.evaluate('(c-c2D)*(r2D<r)',{'c2D':c[:,None],'r2D':r[:,None]})

关于python - 映射对角线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58611604/

相关文章:

python - 如果是空格,如何在不删除分隔符的情况下进行拆分

python - 将多个 int 列/行合并为一个 numpy 数组(pandas 数据框)

python - 使用索引在 Pandas 中查找两个系列之间的交集

javascript - 有没有测量过 CSS 在编码效果方面比 Javascript 快多少?

javascript - 比 Regex 更快的方式匹配字符串之间的字符?

python - 知道一个项目在数组中的位置

python - 提取json字段并用python将它们写入csv

python - 如何获取每个打开窗口的名称列表?

python - pandas groupby 中的 as_index 是什么?

php - 将多次访问的具有常量值的数组放在哪里?