Какой наиболее эффективный способ разделить Numpy ndarray с использованием процента?

#python #numpy #numpy-ndarray

#python #тупой #numpy-ndarray

Вопрос:

Привет, я новичок в Python и Numpy, и я хотел бы спросить, какой наиболее эффективный способ разделить ndarray на 3 части: 20%, 60% и 20%

     import numpy as np
    row_indices = np.random.permutation(10)
 

Предположим, что ndarray содержит 10 элементов: [7 9 3 1 2 4 5 6 0 8]
Ожидаемые результаты — это ndarray, разделенный на 3 части, такие как part1, part2 и part3.
часть 1: [7 9]
часть 2: [3 1 2 4 5]
часть 3: [08]

Ответ №1:

Вот один из способов —

 # data array
In [85]: a = np.array([7, 9, 3, 1, 2, 4, 5, 6, 0, 8])

# percentages (ratios) array
In [86]: p = np.array([0.2,0.6,0.2]) # must sum upto 1

In [87]: np.split(a,(len(a)*p[:-1].cumsum()).astype(int))
Out[87]: [array([7, 9]), array([3, 1, 2, 4, 5, 6]), array([0, 8])]
 

Альтернатива np.split :

np.split может быть медленнее при работе с большими данными, поэтому мы могли бы в качестве альтернативы использовать цикл там —

 split_idx = np.r_[0,(len(a)*p.cumsum()).astype(int)]
out = [a[i:j] for (i,j) in zip(split_idx[:-1],split_idx[1:])]
 

Ответ №2:

Обычно я просто выбираю наиболее очевидное решение, хотя есть гораздо более причудливые способы сделать то же самое. Реализация занимает секунду и даже не требует отладки (поскольку она чрезвычайно проста)

 part1 = [a[i, ...] for i in range(int(a.shape[0] * 0.2))]
part2 = [a[i, ...] for i in range(int(a.shape[0] * 0.2), int(len(a) * 0.6))]
part3 = [a[i, ...] for i in range(int(a.shape[0] * 0.6), len(a))]
 

Однако следует обратить внимание на несколько вещей

  1. Это округляется, и поэтому вы можете получить что-то, что составляет всего лишь примерно 20-60-20
  2. Вы получаете список элементов, поэтому вам, возможно, придется повторно использовать их с помощью np.asarray()
  3. Вы можете использовать этот метод для индексации нескольких объектов (например, меток и входных данных) для одних и тех же элементов
  4. Если вы получаете индексы один раз перед splits ( indices = list(range(a.shape[0])) ), вы также можете перетасовать их, одновременно заботясь о перетасовке данных