2012-05-15 4 views
0

Пусть я Binned некоторые данные в структуре, как это:биннинговые данные включительно результат

data = {(1,1): [...] # list of float, 
     (1,2): [...], 
     (1,3): [...], 
     (2,1): [...], 
     ... } 

здесь Я только две оси для биннинга, но предположим, что я имею N из них. Теперь предположим, что, например, у меня есть N = 3 оси, и я хочу, данные, где второй бункер 1, так что я хочу есть функция

(None, 1, None) -> [(1, 1, 1), (1, 1, 2), (1, 1, 3), ... 
        (2, 1, 1), (2, 1, 2), (2, 1, 3), ...] 

так что я могу использовать itertools.chain для результата

вы знаете диапазон каждую ось от:

axes_ranges = [(1, 10), (1, 8), (1, 3)] 

других примеров:

(None, 1, 2) -> [(1, 1, 2), (2, 1, 2), (3, 1, 2), ...] 
(None, None, None) -> all the combinations 
(1,2,3) -> [(1,2,3)] 

ответ

1

Кажется очень как вы изобретать колесо. То, что вы, вероятно, захотите использовать, - numpy.ndarray:

import numpy as np 
    >>> x = np.arange(0,27) 
    >>> x 
    array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 
    17, 18, 19, 20, 21, 22, 23, 24, 25, 26]) 
    >>> x.reshape(3,3,3) 
    array([[[ 0, 1, 2], 
    [ 3, 4, 5], 
    [ 6, 7, 8]], 

    [[ 9, 10, 11], 
    [12, 13, 14], 
    [15, 16, 17]], 

    [[18, 19, 20], 
    [21, 22, 23], 
    [24, 25, 26]]]) 

    >>> x[0] 
    array([[0, 1, 2], 
    [3, 4, 5], 
    [6, 7, 8]]) 
    >>> x[:,1,:] 
    array([[ 3, 4, 5], 
    [12, 13, 14], 
    [21, 22, 23]]) 
    >>> x[:,1,1] 
    array([ 4, 13, 22]) 

Это может иметь размеры N. В примере индексирование является трехмерным, вы можете видеть его как куб с x [a, b, c] = x [слой, строка, столбец]. Использование индекса «:» в качестве индекса просто означает «все»

+0

это здорово, проблемы теперь в 2: 1. как перевести '(None, 1, 1)' to x [:, 1 , 1]? Какими символами являются ':'? 2. Мои данные не являются int (или float): для каждого бина у меня есть коллекция (список) поплавков –

+0

- это списки с плавающей точкой равной длины? – Schuh

+0

нет, они не –

1

ттт, как бой:

import itertools 

def combinations_with_fixpoint(iterables, *args): 
    return itertools.product(*([x] if x else y for x, y in zip(args, iterables))) 


axes_ranges = [(1, 7), (1, 8), (77, 79)] 

combs = combinations_with_fixpoint(
    itertools.starmap(range, axes_ranges), 
    None, 5, None 
) 

for p in combs: 
    print p 

# (1, 5, 77) 
# (1, 5, 78) 
# (2, 5, 77) 
# (2, 5, 78) 
# (3, 5, 77) 
# (3, 5, 78) 
# (4, 5, 77) 
# (4, 5, 78) 
# (5, 5, 77) 
# (5, 5, 78) 
# (6, 5, 77) 
# (6, 5, 78)  

из, может быть, просто передать список, чтобы несколько "твердых точек":

def combinations_with_fixpoint(iterables, *args): 
    return itertools.product(*(x or y for x, y in zip(args, iterables))) 

combs = combinations_with_fixpoint(
    itertools.starmap(range, axes_ranges), 
    None, [5, 6], None 
) 
+0

действительно лучше, чем у меня –

0
binning = [[0, 0.1, 0.2], [0, 10, 20], [-1, -2, -3]] 
range_binning = [(1, len(x) + 1) for x in binning] 

def expand_bin(thebin): 
    def expand_bin_index(thebin, freeindex, rangebin): 
     """ 
     thebin = [1, None, 3] 
     freeindex = 1 
     rangebin = [4,5] 
     -> [[1, 4, 3], [1, 5, 3]] 
     """ 
     result = [] 
     for r in rangebin: 
      newbin = thebin[:] 
      newbin[freeindex] = r 
      result.append(newbin) 
     return result 

    tmp = [thebin] 
    indexes_free = [i for i,aa in enumerate(thebin) if aa is None] 
    for index_free in indexes_free: 
     range_index = range(*(range_binning[index_free])) 
     new_tmp = [] 
     for t in tmp: 
      for expanded in expand_bin_index(t, index_free, range_index): 
       new_tmp.append(expanded) 
     tmp = new_tmp 
    return tmp 

inputs = ([None, 1, 2], [None, None, 3], [None, 1, None], [3, 2, 1], [None, None, None]) 
for i in inputs: 
    print "%s-> %s" % (i, expand_bin(i)) 
Смежные вопросы