Перебазирование списка чисел в python

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

До сих пор я уже написал некоторый код, который делает то, что я хочу, но он не очень эффективен. Учитывая список a, чтобы перебрать его с шириной корзины, равной 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 и весь процесс занимает очень много времени (часов...). У вас есть идеи по улучшению этого кода? Заранее спасибо!

2 ответа

Решение

Если вы используете 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].

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

Другие вопросы по тегам