我有一个带有一些重复值的排序数组。如何将这个数组转换成一个数组数组,子数组按值分组(见下文)?实际上,my_first_array有大约800万个条目,因此解决方案最好尽可能节省时间。
my_first_array = [1,1,1,3,5,5,9,9,9,9,9,10,23,23]
wanted_array = [ [1,1,1], [3], [5,5], [9,9,9,9,9], [10], [23,23] ]
答案 0 :(得分:4)
itertools.groupby
makes this trivial:
import itertools
wanted_array = [list(grp) for _, grp in itertools.groupby(my_first_array)]
如果没有key
函数,则只有yield
个由相同值组合运行的组,因此您list
- ify列表理解中的每一个;十分简单。您可以将其视为用于执行GNU工具包程序uniq
和相关操作的Python内部API。
在CPython(引用解释器)中,groupby
在C中实现,它以懒惰和线性方式运行;数据必须已经出现在与key
函数匹配的运行中,因此排序可能会使它过于昂贵,但对于已经排序的数据,就像你拥有的那样,没有什么比这更有效了。
注意:如果输入可能是相同但不同的对象,则可能因内存原因将list(grp) for _, grp
更改为[k] * len(list(grp)) for k, grp
。前者将在最终结果中保留原始(可能是值但不是标识副本)对象,后者将从每个组中复制第一个对象,从而将每个组的最终成本降低到N
引用的成本。单个对象,而不是对N
和1
个对象之间的N
个引用。
答案 1 :(得分:2)
我假设输入是一个NumPy数组,你正在寻找一个数组列表作为输出。现在,您可以将输入数组拆分为索引,其中这些移位(重复组具有边界)与np.split
。要查找此类索引,有两种方法 - 使用np.unique
将其可选参数return_index
设置为True
,将另一种方法与np.where
和np.diff
组合使用。因此,我们将采用下面列出的两种方法。
使用np.unique
-
import numpy as np
_,idx = np.unique(my_first_array, return_index=True)
out = np.split(my_first_array, idx)[1:]
使用np.where
和np.diff
-
idx = np.where(np.diff(my_first_array)!=0)[0] + 1
out = np.split(my_first_array, idx)
示例运行 -
In [28]: my_first_array
Out[28]: array([ 1, 1, 1, 3, 5, 5, 9, 9, 9, 9, 9, 10, 23, 23])
In [29]: _,idx = np.unique(my_first_array, return_index=True)
...: out = np.split(my_first_array, idx)[1:]
...:
In [30]: out
Out[30]:
[array([1, 1, 1]),
array([3]),
array([5, 5]),
array([9, 9, 9, 9, 9]),
array([10]),
array([23, 23])]
In [31]: idx = np.where(np.diff(my_first_array)!=0)[0] + 1
...: out = np.split(my_first_array, idx)
...:
In [32]: out
Out[32]:
[array([1, 1, 1]),
array([3]),
array([5, 5]),
array([9, 9, 9, 9, 9]),
array([10]),
array([23, 23])]
答案 2 :(得分:0)
这是一个解决方案,虽然可能效率不高:
my_first_array = [1,1,1,3,5,5,9,9,9,9,9,10,23,23]
wanted_array = [ [1,1,1], [3], [5,5], [9,9,9,9,9], [10], [23,23] ]
new_array = [ [my_first_array[0]] ]
count = 0
for i in range(1,len(my_first_array)):
a = my_first_array[i]
if a == my_first_array[i - 1]:
new_array[count].append(a)
else:
count += 1
new_array.append([])
new_array[count].append(a)
new_array == wanted_array
答案 3 :(得分:0)
这是O(n):
a = [1,1,1,3,5,5,9,9,9,9,9,10,23,23,24]
res = []
s = 0
e = 0
length = len(a)
while s < length:
b = []
while e < length and a[s] == a[e]:
b.append(a[s])
e += 1
res.append(b)
s = e
print res