4 回答

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()

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)

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]

TA貢獻1812條經驗 獲得超5個贊
這是一個方法
d = {}
for k,v in x:
d[k] = d.get(k,0) + v
x = np.array(list(d.items()))
請記住,這是測試浮動相等性......您可能不應該這樣做
添加回答
舉報