Перебазирование списка чисел в 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, который делает всю работу за вас. Это также хорошо масштабируется.