2016-08-04 2 views
0

У меня вопрос о переписывании списка чисел с желаемой шириной бина. Это в основном то, что делает гистограмма частоты, но мне не нужен сюжет, просто номер ячейки и количество вхождений для каждого бина.Переустановка списка чисел в python

До сих пор я уже написал код, который делает то, что я хочу, но он не очень эффективен. Учитывая список a, чтобы Rebin его с бен шириной, равной 3, я написал следующее:

import os, sys, math 
import numpy as np 

# list of numbers 
a = list(range(3000)) 

# number of entries 
L = int(len(a)) 

# desired bin width 
W = 3 

# number of bins with width W 
N = int(L/W) 

# definition of new empty array 
a_rebin = np.zeros((N, 2)) 

# cycles to populate the new rebinned array 
for n in range(0,N): 
    k = 0 
    for i in range(0,L): 
     if a[i] >= (W*n) and a[i] < (W+W*n): 
      k = k+1 
    a_rebin[n]=[W*n,k] 

# print 
print a_rebin 

Теперь, это именно то, что я хочу, но я думаю, что это не так умны, так как он читает весь список N раз, с N количество ящиков. Это нормально для небольших списков. Но, поскольку мне приходится иметь дело с очень большими списками и относительно небольшими ширинами бинов, это переводится в огромные значения N, и весь процесс занимает очень много времени (часы ...). У вас есть идеи по улучшению этого кода? Заранее спасибо!

ответ

1

Если вы используете a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], ваше решение:

[[0. 3.]
[3. 3.]
[6. 3.]]

Как вы это понимаете? Интервалы равны 0..2, 3..5, 6..8? Я думаю, что тебе что-то не хватает.

Использование numpy.histogram()

hist, bin_edges = numpy.histogram(a, bins=int(len(a)/W)) 
print(hist) 
print(bin_edges) 

Выход:

[3 3 4]
[0. 3. 6. 9.]

У нас есть 4 значения в bin_edges: 0, 3, 6 и 9. Все, кроме последнего (справа), являются полуоткрытыми. Это означает, что у нас есть 3 интервала [0,3), [3,6) и [6,9], и мы имеем 3, 3 и 4 элемента в каждом ящике.
Вы можете определить свои собственные корзины.

import numpy 
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
bins=[0,1,2] 
hist, bin_edges = numpy.histogram(a, bins=bins) 
print(hist) 
print(bin_edges) 

Выход:

[1 2]
[0 1 2]

Теперь у вас есть 1 элемент в [0, 1) и 2-х элементов в [ 1,2].

+0

Ммм да, мой алгоритм пропускает последний бит, но ваше решение объединяет последние два бункера, или так кажется. Для [0,1,2,3,4,5,6,7,8,9] с шириной бина 3 я ожидаю появления как [3,3,3,1], но вы получите [3,3,4 ]. Если я выберу bindwith 5, я ожидаю появления как [5,5], но этот код дает мне края бинов, которые я не понимаю, [0. 4.5 9.] ... Извините, я не очень привык к python ... – urgeo

+0

У нас есть 4 значения в bin_edges: 0, 3, 6 и 9. Все, кроме последнего (справа), являются полуоткрытыми.Это означает, что у нас есть 3 интервала [0,3), [3,6) и [6,9], и мы имеем 3, 3 и 4 элемента в каждом ящике. Вы можете определить свои собственные бункеры: [0,1,2], и теперь у вас есть 1 элемент в [0, 1) и 2 элемента в [1,2]. Хорошо сейчас? –

0

У Numpy есть метод под названием np.histogram, который выполняет эту работу за вас. Он также хорошо масштабируется.

Смежные вопросы