识别一个数组中的重复行并求和另一个数组中的相应值
Identify duplicate rows in an array and sum up corresponding values in another array
假设有一个包含结果的数组和一个包含概率的数组。某些结果可能会被多次列出。例如:
import numpy as np
x = np.array(([0,0],[1,1],[2,1],[1,1],[2,2]),dtype=int)
p = np.array([0.1,0.2,0.3,0.1,0.2],dtype=float)
现在我想在 x
中列出唯一的结果,并将重复结果在 p
中的相应概率相加。所以结果应该是数组 xnew
和 pnew
定义为
xnew = np.array(([0,0],[1,1],[2,1],[2,2]),dtype=int)
pnew = np.array([0.1,0.3,0.3,0.2],dtype=float)
虽然有一些关于如何获取唯一行的示例,但请参阅,例如Removing duplicate columns and rows from a NumPy 2D array ,我不清楚如何使用它来累加另一个数组中的值。
有人有什么建议吗?首选使用 numpy 的解决方案。
不使用 numpy,但可以使用字典来收集相似的值,
import numpy as np
x = np.array(([0,0],[1,1],[2,1],[1,1],[2,2]),dtype=int)
p = np.array([0.1,0.2,0.3,0.1,0.2],dtype=float)
#Initialise dictonary
pdict = {}
for i in x:
pdict[str(i)] = []
#Collect same values using keys
for i in range(x.shape[0]):
pdict[str(x[i])].append(p[i])
#Sum over keys
xnew = []; pnew = []
for key, val in pdict.items():
xnew.append(key)
pnew.append(np.sum(val))
print('xnew = ',np.array(xnew))
print('pnew = ',np.array(pnew))
我将 xnew 值保留为字符串,可以通过某种形式的拆分将其转换回列表。
bincount
可以为你求和p
数组,你只需要为a中的每一行创建一个唯一的id号。如果您使用排序方法来识别唯一行,那么创建唯一 ID 真的很容易。对生成差异数组的行进行排序后,您可以 cumsum
差异数组。例如:
x diff cumsum
[0, 0] 1 1
[0, 0] 0 1
[0, 1] 1 2
[0, 2] 1 3
[1, 0] 1 4
[1, 0] 0 4
[1, 0] 0 4
[1, 0] 0 4
[1, 0] 0 4
[1, 1] 1 5
在代码中,它看起来像这样:
import numpy as np
def unique_rows(a, p):
order = np.lexsort(a.T)
a = a[order]
diff = np.ones(len(a), 'bool')
diff[1:] = (a[1:] != a[:-1]).any(-1)
sums = np.bincount(diff.cumsum() - 1, p[order])
return a[diff], sums
这是一个典型的分组问题,可以使用numpy_indexed包以完全向量化的方式解决(公开:我是它的作者):
import numpy_indexed as npi
xnew, pnew = npi.group_by(x).sum(p)
假设有一个包含结果的数组和一个包含概率的数组。某些结果可能会被多次列出。例如:
import numpy as np
x = np.array(([0,0],[1,1],[2,1],[1,1],[2,2]),dtype=int)
p = np.array([0.1,0.2,0.3,0.1,0.2],dtype=float)
现在我想在 x
中列出唯一的结果,并将重复结果在 p
中的相应概率相加。所以结果应该是数组 xnew
和 pnew
定义为
xnew = np.array(([0,0],[1,1],[2,1],[2,2]),dtype=int)
pnew = np.array([0.1,0.3,0.3,0.2],dtype=float)
虽然有一些关于如何获取唯一行的示例,但请参阅,例如Removing duplicate columns and rows from a NumPy 2D array ,我不清楚如何使用它来累加另一个数组中的值。
有人有什么建议吗?首选使用 numpy 的解决方案。
不使用 numpy,但可以使用字典来收集相似的值,
import numpy as np
x = np.array(([0,0],[1,1],[2,1],[1,1],[2,2]),dtype=int)
p = np.array([0.1,0.2,0.3,0.1,0.2],dtype=float)
#Initialise dictonary
pdict = {}
for i in x:
pdict[str(i)] = []
#Collect same values using keys
for i in range(x.shape[0]):
pdict[str(x[i])].append(p[i])
#Sum over keys
xnew = []; pnew = []
for key, val in pdict.items():
xnew.append(key)
pnew.append(np.sum(val))
print('xnew = ',np.array(xnew))
print('pnew = ',np.array(pnew))
我将 xnew 值保留为字符串,可以通过某种形式的拆分将其转换回列表。
bincount
可以为你求和p
数组,你只需要为a中的每一行创建一个唯一的id号。如果您使用排序方法来识别唯一行,那么创建唯一 ID 真的很容易。对生成差异数组的行进行排序后,您可以 cumsum
差异数组。例如:
x diff cumsum
[0, 0] 1 1
[0, 0] 0 1
[0, 1] 1 2
[0, 2] 1 3
[1, 0] 1 4
[1, 0] 0 4
[1, 0] 0 4
[1, 0] 0 4
[1, 0] 0 4
[1, 1] 1 5
在代码中,它看起来像这样:
import numpy as np
def unique_rows(a, p):
order = np.lexsort(a.T)
a = a[order]
diff = np.ones(len(a), 'bool')
diff[1:] = (a[1:] != a[:-1]).any(-1)
sums = np.bincount(diff.cumsum() - 1, p[order])
return a[diff], sums
这是一个典型的分组问题,可以使用numpy_indexed包以完全向量化的方式解决(公开:我是它的作者):
import numpy_indexed as npi
xnew, pnew = npi.group_by(x).sum(p)