为了账号安全,请及时绑定邮箱和手机立即绑定

合并两个 numpy 数组,一个作为键,另一个作为值

合并两个 numpy 数组,一个作为键,另一个作为值

千万里不及你 2023-07-18 15:37:46
有没有函数可以对 numpy 数组进行 groupby sum ?可能与此重复x = np.array([[1.2, 10],               [2.3, 20],               [1.2, 30],               [2.3, 7]             ])想要的输出:x = np.array([[1.2, 40],               [2.3, 27]                         ])更新:实际上,我的数据的第一列总是四舍五入到小数点后两位。所以x可以写成:x = np.array([[120, 10],               [230, 20],               [120, 30],               [230, 7]             ])
查看完整描述

4 回答

?
慕娘9325324

TA贡献1783条经验 获得超4个赞

我不会说这是重复的,但您提到的相关问题是一个很好的起点。您链接的大多数答案都需要对数组进行排序,提取组开始的索引,然后调用np.split它。这里不是这种情况,因为它会返回一个大小不平衡的组列表。


相反,您可以使用np.bincount方法。它计算每个加权值出现的次数,这实际上与 groupby sum 相同,只是输出中缺少组键。


def group_by_sum(x):

    u, idx = np.unique(x[:,0], return_inverse=True)

    s = np.bincount(idx, weights = x[:,1])

    return np.c_[u, s]

奖金。它实际上是numpy_indexed包装中的一个单行:


np.transpose(npi.group_by(x[:, 0]).sum(x[:, 1]))

标杆管理

import numpy as np

import perfplot

import matplotlib.pyplot as plt


def bincount(x):

    u, idx = np.unique(x[:,0], return_inverse=True)

    s = np.bincount(idx, weights = x[:,1])

    return np.c_[u, s]


def reduceat(x):

    x = x[np.argsort(x[:, 0])]

    i = np.flatnonzero(np.diff(x[:, 0]))

    i = np.r_[0, i + 1]

    s = np.add.reduceat(x[:, 1], i)

    return np.stack((x[i, 0], s), axis=-1)


def setup(N, s):

    x = np.linspace(0,1,N+1)[np.random.randint(N, size = s)]

    return np.c_[x, (x**2)%1]


def build_args(k):

    return {'setup': lambda x: setup(k, x),

            'kernels': [bincount, reduceat],

            'n_range': [2**k for k in range(1, 20)],

            'title': f'Testing for x samples in [0, 1] with no more than {k} groups',

            'show_progress': True,

            'equality_check': False}


outs = [perfplot.bench(**build_args(n)) for n in (10, 100, 1000, 10000)]

fig = plt.figure(figsize=(20, 20))

for i in range(len(outs)):

    ax = fig.add_subplot(2, 2, i + 1)

    ax.grid(True, which="both")

    outs[i].plot()

plt.show()

//img1.sycdn.imooc.com//64b6417d00014c8e12790674.jpg

查看完整回答
反对 回复 2023-07-18
?
不负相思意

TA贡献1777条经验 获得超10个赞

Numpy 提供了无需显式循环即可完成此操作的工具。

首先对行进行排序:

a = a[np.argsort(a[:, 0])]

然后找到值发生变化的索引:

i = np.flatnonzero(np.diff(a[:, 0]))
i = np.r_[0, i + 1]

然后将元素相加:

s = np.add.reduceat(a[:, 1], i)

索引只是a每次运行中的第一个元素,因此结果是

result = np.stack((a[i, 0], s), axis=-1)


查看完整回答
反对 回复 2023-07-18
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

这是一个使用唯一值来计算每个元素的重复次数并将其乘以其值来计算 groupby 总和的解决方案(您可以通过实现仅计算重复和唯一值的哈希图来更快地实现它)O(n):


编辑原始问题已编辑:


keys2, idx, count = np.unique(x[:,0], return_counts=True, return_index=True)

values2 = x[:,1][idx]*count

另一种方法是使用 pandas groupby:


df = pd.DataFrame({'keys':x[:,0], 'values':x[:,1]})

df2 = df.groupby(keys)['values'].agg('sum')

keys2, values2 = df2.index.to_numpy(), df2.values

输出:


[1.2 2.3] 

[20 30]


查看完整回答
反对 回复 2023-07-18
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

这是一个方法


d = {}

for k,v in x:

    d[k] = d.get(k,0) + v


x = np.array(list(d.items()))

请记住,这是测试浮动相等性......您可能不应该这样做


查看完整回答
反对 回复 2023-07-18
  • 4 回答
  • 0 关注
  • 115 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信