[英]Merging records in a Numpy structured array
我有一个Numpy结构化数组,按第一列排序:
x = array([(2, 3), (2, 8), (4, 1)], dtype=[('recod', '<u8'), ('count', '<u4')])
我需要合并记录(总和第二列的值)在哪里
x[n][0] == x[n + 1][0]
在这种情况下,所需的输出将是:
x = array([(2, 11), (4, 1)], dtype=[('recod', '<u8'), ('count', '<u4')])
实现这一目标的最佳方法是什么?
您可以使用np.unique
为第一列中的每个元素获取一个ID数组,然后使用np.bincount
根据ID在第二列元素上执行累积 -
In [140]: A
Out[140]:
array([[25, 1],
[37, 3],
[37, 2],
[47, 1],
[59, 2]])
In [141]: unqA,idx = np.unique(A[:,0],return_inverse=True)
In [142]: np.column_stack((unqA,np.bincount(idx,A[:,1])))
Out[142]:
array([[ 25., 1.],
[ 37., 5.],
[ 47., 1.],
[ 59., 2.]])
你能避免np.unique
与组合np.diff
和np.cumsum
这可能会帮助,因为np.unique
也没有内部的排序,这是没有必要在这种情况下,作为输入数据已经排序。 实现看起来像这样 -
In [201]: A
Out[201]:
array([[25, 1],
[37, 3],
[37, 2],
[47, 1],
[59, 2]])
In [202]: unq1 = np.append(True,np.diff(A[:,0])!=0)
In [203]: np.column_stack((A[:,0][unq1],np.bincount(unq1.cumsum()-1,A[:,1])))
Out[203]:
array([[ 25., 1.],
[ 37., 5.],
[ 47., 1.],
[ 59., 2.]])
In [285]: import pandas as pd
In [286]: x = [(25, 1), (37, 3), (37, 2), (47, 1), (59, 2)]
In [287]: df = pd.DataFrame(x)
In [288]: df
Out[288]:
0 1
0 25 1
1 37 3
2 37 2
3 47 1
4 59 2
In [289]: df.groupby(0).sum()
Out[289]:
1
0
25 1
37 5
47 1
59 2
如果这是您需要的唯一操作,您可能不希望依赖于pandas,但是一旦开始,您可能会在库中找到其他有用的位。
Dicakar's
答案采用结构化数组形式:
In [500]: x=np.array([(25, 1), (37, 3), (37, 2), (47, 1), (59, 2)], dtype=[('recod', '<u8'), ('count', '<u4')])
查找唯一值并计算重复项:
In [501]: unqA, idx=np.unique(x['recod'], return_inverse=True)
In [502]: cnt = np.bincount(idx, x['count'])
创建一个新的结构化数组并填充字段:
In [503]: x1 = np.empty(unqA.shape, dtype=x.dtype)
In [504]: x1['recod'] = unqA
In [505]: x1['count'] = cnt
In [506]: x1
Out[506]:
array([(25, 1), (37, 5), (47, 1), (59, 2)],
dtype=[('recod', '<u8'), ('count', '<u4')])
有一个recarray
函数可以从一个数组列表构建一个数组:
In [507]: np.rec.fromarrays([unqA,cnt],dtype=x.dtype)
Out[507]:
rec.array([(25, 1), (37, 5), (47, 1), (59, 2)],
dtype=[('recod', '<u8'), ('count', '<u4')])
在内部它做同样的事情 - 构建一个正确大小和dtype的空数组,然后遍历dtype字段。 重新排列只是专用数组子类包装器中的结构化数组。
有两种方法可以填充结构化数组(特别是使用不同的dtype) - 使用x
表示元组列表,逐字段表示。
你可以使用np.reduceat
。 你只需要填充x[:, 0]
更改的位置,这相当于np.diff(x[:,0])
非零索引移位一加上初始索引0:
>>> i = np.r_[0, 1 + np.nonzero(np.diff(x[:,0]))[0]]
>>> a, b = x[i, 0], np.add.reduceat(x[:, 1], i)
>>> np.vstack((a, b)).T
array([[25, 1],
[37, 5],
[47, 1],
[59, 2]])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.