根据2列值取numpy数组的唯一值,

dsekswqp  于 2023-05-17  发布在  其他
关注(0)|答案(4)|浏览(109)

我在python中有一个Numpy数组,其中有两列,如下所示:

time,id
1,a
2,b
3,a
1,a
5,c
6,b
3,a

我想采取每个用户的唯一时间。对于以上数据,我想下面的输出。

time,id
1,a
2,b
3,a
5,c
6,b

也就是说,我只想取唯一的行。因此,1,a和3,a在结果中不会重复。我有两个字符串数据类型的列,并有一个非常大的二维数组。一个解决方案可能是,我可以迭代所有行并建立一个集合。但那会很慢。请提出一个有效的方法来实现它。

k3fezbri

k3fezbri1#

给出:

>>> b
[['1' 'a']
 ['2' 'b']
 ['3' 'a']
 ['1' 'a']
 ['5' 'c']
 ['6' 'b']
 ['3' 'a']]

您可以:

>>> np.vstack({tuple(e) for e in b})
[['3' 'a']
 ['1' 'a']
 ['2' 'b']
 ['6' 'b']
 ['5' 'c']]

因为这是一个固定的理解,你失去了原来的顺序。
或者,为了维持秩序,您可以:

>>> c = np.ascontiguousarray(b).view(np.dtype((np.void, b.dtype.itemsize * b.shape[1])))
>>> b[np.unique(c, return_index=True)[1]]
[['1' 'a']
 ['2' 'b']
 ['3' 'a']
 ['5' 'c']
 ['6' 'b']]

或者,如果你可以使用Pandas,这真的很容易。给定以下DataFrame:

>>> df
  id  time
0  a     1
1  b     2
2  a     3
3  a     1
4  c     5
5  b     6
6  a     3

使用drop_duplicates()

>>> df.drop_duplicates()
  id  time
0  a     1
1  b     2
2  a     3
4  c     5
5  b     6
zyfwsgd6

zyfwsgd62#

如果返回到原始列表格式数据并创建结构化数组,则确定唯一值要容易得多。

a = [['1', 'a'], ['2', 'b'], ['3', 'a'],['1', 'a'],['5', 'c'], ['6', 'b'], ['3', 'a']]

tup = [tuple(i) for i in a]  # you need a list of tuples, a kludge for now

dt = [('f1', '<U5'), ('f2', '<U5')]  # specify a dtype with two columns

b = np.array(tup, dtype=dt)  # create the array with the dtype

np.unique(b)  # get the unique values
array([('1', 'a'), ('2', 'b'), ('3', 'a'), ('5', 'c'), ('6', 'b')], 
      dtype=[('f1', '<U5'), ('f2', '<U5')])

np.unique(b).tolist()  # and if you need a list, just change the array
[('1', 'a'), ('2', 'b'), ('3', 'a'), ('5', 'c'), ('6', 'b')]

参考:Find unique rows in numpy.array
Joe金斯顿和Jaime的建议结合起来处理观点,上面的建议可以简化为以下内容。很好地,这个选项依赖于视图,将dtype更改为结构化数组,并使用结构化视图中唯一值的索引对原始数组进行切片。

>>> dt = a.dtype.descr * a.shape[1]
>>> a_view = a.view(dt)
>>> a_uniq, a_idx = np.unique(a_view, return_index=True)
>>> a[a_idx]
array([['1', 'a'],
       ['2', 'b'],
       ['3', 'a'],
       ['5', 'c'],
       ['6', 'b']], 
      dtype='<U1')
ef1yzkbh

ef1yzkbh3#

对于未来的读者来说,一种纯粹的numpy方法可以基于特定行/列删除重复项:

x = np.array(
[[1,'a'],
[2,'b'],
[3,'a'],
[1,'a'],
[5,'c'],
[6,'b'],
[3,'a']])

print(x[np.unique(x[:,0], axis=0, return_index=True)[1]])

>>[['1' 'a']
   ['2' 'b']
   ['3' 'a']
   ['5' 'c']
   ['6' 'b']]

或多于一个列:

print(x[np.unique(x[:,[0, 1]], axis=0, return_index=True)[1]])
qpgpyjmq

qpgpyjmq4#

如果有人仍然需要它,这里有一个一行程序:-)
请注意,这要求所有列值具有相同的dtype!

import numpy as np
a = [[1, "a"], [1, "b"], [1, "c"], [2, "a"], [2, "b"], [2, "c"],
     [1, "a"], [1, "b"], [1, "c"], [2, "a"], [2, "b"], [2, "c"]]

unique_a = np.unique(np.rec.fromrecords(a)).tolist()
>>> [(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c')]

相关问题