Я - binning 2-й массив (x на годы) в Python в мусорные ведра его значения x (данный в "мусорных ведрах"), с помощью np.digitize:
elements_to_bins = digitize(vals, bins)
где "vals" является 2-м массивом, т.е.:
vals = array([[1, v1], [2, v2], ...]).
elements_to_bins просто говорит, в какое мусорное ведро каждый элемент падает. То, что я затем хочу сделать, получают список, длина которого является количеством мусорных ведер в "мусорных ведрах", и каждый элемент возвращает y-размер "vals", который попадает в то мусорное ведро. Я делаю это этот путь прямо сейчас:
points_by_bins = []
for curr_bin in range(min(elements_to_bins), max(elements_to_bins) + 1):
curr_indx = where(elements_to_bins == curr_bin)[0]
curr_bin_vals = vals[:, curr_indx]
points_by_bins.append(curr_bin_vals)
существует ли более изящный/более простой способ сделать это? Все, в чем я нуждаюсь, является списком списков y-значений, которые попадают в каждое мусорное ведро.
спасибо.
Если я правильно понял ваш вопрос:
vals = array([[1, 10], [1, 11], [2, 20], [2, 21], [2, 22]]) # Example
(x, y) = vals.T # Shortcut
bin_limits = range(min(x)+1, max(x)+2) # Other limits could be chosen
points_by_bin = [ [] for _ in bin_limits ] # Final result
for (bin_num, y_value) in zip(searchsorted(bin_limits, x, "right"), y): # digitize() finds the correct bin number
points_by_bin[bin_num].append(y_value)
print points_by_bin # [[10, 11], [20, 21, 22]]
Для максимальной эффективности используется быстрая операция Numpy с массивами searchsorted()
. Значения затем добавляются по одному (поскольку конечный результат не является прямоугольным массивом, Numpy не может сильно помочь в этом). Это решение должно быть быстрее, чем несколько вызовов where()
в цикле, которые заставляют Numpy многократно перечитывать один и тот же массив.
Являются ли ключи бункера просто целыми числами, без биннинга, как в вашем примере? Тогда вы могли бы просто сделать это без numpy:
from collections import defaultdict
bins = defaultdict(list) # or [ [] ...] as in EOL
vals = [[1, 10], [1, 11], [2, 20], [2, 21], [2, 22]] # nparray.tolist()
for nbin, val in vals:
bins[nbin].append(val)
print "bins:", bins
# defaultdict(<type 'list'>, {1: [10, 11], 2: [20, 21, 22]})