【问题标题】:Summing and removing repeated elements of Numpy Arrays求和和删除 Numpy 数组的重复元素
【发布时间】:2014-09-12 00:56:51
【问题描述】:

我有 4 个等长的 1D Numpy 数组。 前三个充当 ID,唯一标识第 4 个数组。

ID 数组包含重复组合,为此我需要对第 4 个数组求和,并从所有 4 个数组中删除重复元素。

x = np.array([1, 2, 4, 1])
y = np.array([1, 1, 4, 1])
z = np.array([1, 2, 2, 1])
data = np.array([4, 7, 3, 2])

在这种情况下我需要:

x = [1, 2, 4]
y = [1, 1, 4]
z = [1, 2, 2]
data = [6, 7, 3]

数组相当长,所以循环真的不起作用。我确信有一个相当简单的方法可以做到这一点,但对于我的生活,我无法弄清楚。

【问题讨论】:

  • 我不确定您要做什么,但是 np.unique() 和 np.sum() 的某种组合应该可以做到吗?

标签: python arrays numpy


【解决方案1】:

首先,我们可以将 ID 向量堆叠成一个矩阵,这样每个 ID 就是一行三个值:

XYZ = np.vstack((x,y,z)).T

现在,我们只需要找到重复行的索引。可惜np.unique不对行进行操作,所以我们需要do some tricks

order = np.lexsort(XYZ.T)
diff = np.diff(XYZ[order], axis=0)
uniq_mask = np.append(True, (diff != 0).any(axis=1))

这部分是从np.unique source code借来的,找到唯一索引以及“逆索引”映射:

uniq_inds = order[uniq_mask]
inv_idx = np.zeros_like(order)
inv_idx[order] = np.cumsum(uniq_mask) - 1

最后,对唯一索引求和:

data = np.bincount(inv_idx, weights=data)
x,y,z = XYZ[uniq_inds].T

【讨论】:

  • data = np.bincount(inv_idx, weights=data) 是在 numpy 中添加重复的快速方法。
  • 非常感谢,这非常有效。在我拥有的数据(~120k 长数组)上计时大约需要 1.4 秒。 @wasserfeder 的解决方案似乎有效,但耗时约 28 秒。
  • 另外,在 2D 数组中查找唯一行可能会稍快一些,有很多讨论 here
【解决方案2】:

您可以按照 reptilicus 的建议使用 unique 和 sum 来执行以下操作

from itertools import izip
import numpy as np

x = np.array([1, 2, 4, 1])
y = np.array([1, 1, 4, 1])
z = np.array([1, 2, 2, 1])
data = np.array([4, 7, 3, 2])

# N = len(x)
# ids = x + y*N + z*(N**2)
ids = np.array([hash((a, b, c)) for a, b, c in izip(x, y, z)]) # creates flat ids

_, idx, idx_rep = np.unique(ids, return_index=True, return_inverse=True)

x_out = x[idx]
y_out = y[idx]
z_out = z[idx]
# data_out = np.array([np.sum(data[idx_rep == i]) for i in idx])
data_out = np.bincount(idx_rep, weights=data)

print x_out
print y_out
print z_out
print data_out

【讨论】:

    猜你喜欢
    • 2018-04-06
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    相关资源
    最近更新 更多