Рандомизация массива в два массива - PullRequest
0 голосов
/ 03 марта 2011

У меня есть список чисел, и мне нужно разбить на соответствующие массивы разных размеров, но они составляют все комбинации разделения массива.Например, если у меня есть массив 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 ]

1 голос
/ 04 марта 2011

Это решение должно быть более эффективным для больших массивов, так как оно использует 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_one и col_two, вычисляя нужные статистические данные в цикле и сохраняя их вместо этого.

0 голосов
/ 03 марта 2011

Я проверил ваш код и вижу проблему.В этом коде

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 с именем 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]

Объединяя все это вместе:

number = [53, 64, 68, 71, 77, 82, 85]
col_one = list(itertools.combinations(number, 4))
col_two = [[n for n in number if n not in c1_list] for c1_list in col_one]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...