我在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将不会重复结果。 我将列作为字符串数据类型并且具有非常大的2-D数组。 一个解决方案可能是,我可以迭代所有行并创建一个集合。但那将是非常缓慢的。请建议一种有效的方法来实现它。
答案 0 :(得分:3)
假设:
>>> 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
答案 1 :(得分:0)
如果您回到原始列表格式数据并创建结构化数组,那么确定唯一值会更容易。
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 Kingston和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')
答案 2 :(得分:0)
对于未来的读者来说,这是一种基于特定行/列删除重复项的纯 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']]