You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对有序二维numpy数组首列重复元素的第二列求和?

解决有序numpy数组首列重复元素的第二列求和问题

方法一:使用numpy的unique与bincount(适用于首列唯一值无需严格保持原顺序,或原唯一值已排序的情况)

import numpy as np

y = np.array(([14.0, 100], [15.0, 130], [15.0, -90], [16.0, 60]))

# 获取首列的唯一值及对应分组索引
unique_keys, group_indices = np.unique(y[:, 0], return_inverse=True)
# 按分组索引对第二列求和
sum_values = np.bincount(group_indices, weights=y[:, 1])
# 组合成目标数组
z = np.column_stack((unique_keys, sum_values))

print(z)
# 输出:
# [[ 14. 100.]
#  [ 15.  40.]
#  [ 16.  60.]]

方法二:基于数组拆分(适用于首列重复元素连续的有序数组,严格保持原顺序)

如果原数组首列的重复元素是连续排列的(像示例这样),可以通过拆分数组实现:

import numpy as np

y = np.array(([14.0, 100], [15.0, 130], [15.0, -90], [16.0, 60]))

# 定位首列元素变化的位置
split_positions = np.where(y[1:, 0] != y[:-1, 0])[0] + 1
# 按位置拆分数组为分组
groups = np.split(y, split_positions)
# 每组取首列第一个值,第二列求和后组合
z = np.array([[group[0, 0], group[:, 1].sum()] for group in groups])

print(z)
# 输出与示例一致

方法三:借助pandas分组(简洁直观,严格保持原顺序)

如果项目中已引入pandas,这种写法更易懂:

import pandas as pd
import numpy as np

y = np.array(([14.0, 100], [15.0, 130], [15.0, -90], [16.0, 60]))

# 转换为DataFrame
df = pd.DataFrame(y, columns=["key", "value"])
# 按key分组求和,sort=False保持原顺序
result_df = df.groupby("key", as_index=False, sort=False)["value"].sum()
# 转回numpy数组
z = result_df.to_numpy()

print(z)

关于reduce/map/lambda的尝试说明

用reduce也能实现,但numpy数组更适合向量化操作,循环式的reduce效率较低,示例实现如下:

from functools import reduce
import numpy as np

y = np.array(([14.0, 100], [15.0, 130], [15.0, -90], [16.0, 60]))

def merge_groups(result, current_item):
    if not result:
        return [current_item.tolist()]
    last_group = result[-1]
    if last_group[0] == current_item[0]:
        last_group[1] += current_item[1]
        return result
    result.append(current_item.tolist())
    return result

result_list = reduce(merge_groups, y, [])
z = np.array(result_list)

print(z)

内容的提问来源于stack exchange,提问作者cmmc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 15:10:32