一个非常大的numpy数组按ID分组的最快方法

时间:2015-11-13 16:50:25

标签: python arrays numpy

我正在努力寻找分组行的最佳方法。具有相似的ID。

我最好的猜测: np.array([test[test[:,0] == ID] for ID in List_IDs])

结果:数组数组

[ array([['ID_1', 'col1','col2',...,'coln'],
         ['ID_1', 'col1','col2',...,'coln'],...,
         ['ID_1', 'col1','col2',...,'coln']],dtype='|S32')
array([['ID_2', 'col1','col2',...,'coln'],
         ['ID_2', 'col1','col2',...,'coln'],...,
         ['ID_2', 'col1','col2',...,'coln']],dtype='|S32')
....
array([['ID_k', 'col1','col2',...,'coln'],
         ['ID_k', 'col1','col2',...,'coln'],...,
         ['ID_K', 'col1','col2',...,'coln']],dtype='|S32')]

任何人都可以提出更高效的建议吗?

提醒:test数组很大。 '行'没有订购

1 个答案:

答案 0 :(得分:2)

我假设List_IDs是第一列中所有唯一ID的列表。有了这个假设,这是一个基于Numpy的解决方案 -

# Sort input array test w.r.t. first column that are IDs
test_sorted = test[test[:,0].argsort()]

# Convert the string IDs to numeric IDs
_,numeric_ID = np.unique(test_sorted[:,0],return_inverse=True)

# Get the indices where shifts (IDs change) occur
_,cut_idx = np.unique(numeric_ID,return_index=True)

# Use the indices to split the input array into sub-arrays with common IDs
out = np.split(test_sorted,cut_idx)[1:]

示例运行 -

In [305]: test
Out[305]: 
array([['A', 'A', 'B', 'E', 'A'],
       ['B', 'E', 'A', 'E', 'B'],
       ['C', 'D', 'D', 'A', 'C'],
       ['B', 'D', 'A', 'C', 'A'],
       ['B', 'A', 'E', 'A', 'E'],
       ['C', 'D', 'C', 'E', 'D']], 
      dtype='|S32')

In [306]: test_sorted
Out[306]: 
array([['A', 'A', 'B', 'E', 'A'],
       ['B', 'E', 'A', 'E', 'B'],
       ['B', 'D', 'A', 'C', 'A'],
       ['B', 'A', 'E', 'A', 'E'],
       ['C', 'D', 'D', 'A', 'C'],
       ['C', 'D', 'C', 'E', 'D']], 
      dtype='|S32')

In [307]: out
Out[307]: 
[array([['A', 'A', 'B', 'E', 'A']], 
       dtype='|S32'), array([['B', 'E', 'A', 'E', 'B'],
        ['B', 'D', 'A', 'C', 'A'],
        ['B', 'A', 'E', 'A', 'E']], 
       dtype='|S32'), array([['C', 'D', 'D', 'A', 'C'],
        ['C', 'D', 'C', 'E', 'D']], 
       dtype='|S32')]