将数组随机化为两个数组

时间:2011-03-03 05:47:28

标签: python numpy scipy

我有一个数字列表,我需要分成不同大小的相应数组,但这组成了数组拆分的所有组合。例如,如果我有一个数组a=[1,2,3,4,5],我想将它拆分为一个大小为3的数组,另一个数组为2.

所以我想要制作两个数组来保存每个数组,因为有相同数量的3号和2号数组,我可以匹配它们,然后执行我的测试。 (这是一个统计类,所以如果有一个更好的scipy或numpy实现我喜欢听它,因为我想移动使用那些,最后我想得到不同的手段之间的所有差异阵列)

但是我的代码是

import itertools


#defines the array of numbers and the two columns
number = [53, 64, 68, 71, 77, 82, 85]
col_one = []
col_two = []

#creates an array that holds the first four
results = itertools.combinations(number,4)

for x in results:
col_one.append(list(x))

print col_one


#attempts to go through and remove those numbers in the first array
#and then add that array to col_two
for i in range(len(col_one)):
holder = number
for j in range(4):
    holder.remove(col_one[i][j])
col_two.append(holder)  

提前致谢

编辑:它似乎是混乱的代码间距 - 我向你保证间距是可以的,虽然当我运行代码时我无法从holder删除一个项目,因为它不存在。

2 个答案:

答案 0 :(得分:1)

对于大型数组,此解决方案应该更有效,因为它使用set来计算第二个数组的索引,并预先分配内存:

import scipy as sp
import itertools

number = sp.array([53, 64, 68, 71, 77, 82, 85])
len_number = len(number)

# number of combinations
ncomb = sp.comb(len_number, 4)
# pre-allocate memory
col_one = sp.empty((ncomb, 4))
col_two = sp.empty((ncomb, len_number-4))

indices = range(len_number)
indices_set = set(indices)
for i, idx in enumerate(itertools.combinations(indices, 4)):
    col_one[i,:] = number[list(idx)]
    col_two[i,:] = number[list(indices_set.difference(idx))]

通过生成长度为len_number且包含4个True值的所有布尔数组,可以获得更高效的解决方案,这将允许您编写

col_one[i,:] = number[bool_idx]
col_two[i,:] = number[sp.logical_not(bool_idx)]

如果可能的话,我会避免通过在循环中计算所需的统计数据并存储它们来存储col_onecol_two

答案 1 :(得分:0)

我测试了你的代码,我发现了问题。在此代码中,

for i in range(len(col_one)):
    holder = number
    for j in range(4):
        holder.remove(col_one[i][j])
    col_two.append(holder)

holder = number不会复制number,只会给number第二个名称holder。然后,当您从holder移除内容时,它们也会从number中移除,因此当循环再次出现时,数字中的数字会少四个。广告无限。

您想要复制数字:

for i in range(len(col_one)):
    holder = list(number)
    for j in range(4):
        holder.remove(col_one[i][j])
    col_two.append(holder)

这会从名为number的{​​{1}}创建一个新列表。现在只更改了holder

holder

也会奏效。

您还应该通过避免索引变量来使用 holder = number[:] 的全部潜力:

for

这也是一样的,更容易阅读,可能更快启动。

现在进行下一步,列出理解。这是避免嵌套循环的好方法。

for num_list in col_one:
    holder = list(number)
    for num in num_list:
        holder.remove(num)
    col_two.append(holder)

这与上面的内容相同。你甚至可以把它作为一个单行:

for c1_list in col_one:
    c2_list = [n for n in number if n not in c1_list]
    col_two.append(c2_list)

将它们组合在一起:

col_two = [[n for n in number if n not in c1_list] for c1_list in col_one]