В идеале я хочу следующее, не читая данные с жесткого диска слишком много раз. Данные большие, и память не может одновременно хранить все данные.Разделите поток в бункеры с равными значениями
- Ввод - это поток
x[t]
с жесткого диска. В потоке чисел содержитсяN
элементов. - Возможно иметь гистограмму
x
сm
ячейками. - п бункера определяются мусорными ребра х < е ..., < х м. Например, если е я = < х [0] < е + 1, то х [0] принадлежит к I-й бин.
- Найти края бункеров, которые делают лоток, содержит почти равное количество элементов из потока. Количество элементов в каждом бункере должно быть идеально в пределах некоторого порогового процента от
N/m
. Это связано с тем, что, если мы равномерно распределяемN
элементов среди m бункеров, каждая ячейка должна содержать околоN/m
элементов.
Текущее решение:
import numpy as np
def test_data(size):
x = np.random.normal(0, 0.5, size // 2)
x = np.hstack([x, np.random.normal(4, 1, size // 2)])
return x
def bin_edge_as_index(n_bin, fine_hist, fine_n_bin, data_size):
cum_sum = np.cumsum(fine_hist)
bin_id = np.empty((n_bin + 1), dtype=int)
count_per_bin = data_size * 1.0/n_bin
for i in range(1, n_bin):
bin_id[i] = np.argmax(cum_sum > count_per_bin * i)
bin_id[0] = 0
bin_id[n_bin] = fine_n_bin
return bin_id
def get_bin_count(bin_edge, data):
n_bin = bin_edge.shape[0] - 1
result = np.zeros((n_bin), dtype=int)
for i in range(n_bin):
cmp0 = (bin_edge[i] <= data)
cmp1 = (data < bin_edge[i + 1])
result[i] = np.sum(cmp0 & cmp1)
return result
# Test Setting
test_size = 10000
n_bin = 6
fine_n_bin = 2000 # use a big number and hope it works
# Test Data
x = test_data(test_size)
# Fine Histogram
fine_hist, fine_bin_edge = np.histogram(x, fine_n_bin)
# Index of the bins of the fine histogram that contains
# the required bin edges (e_1, e_2, ... e_n)
bin_id = bin_edge_as_index(
n_bin, fine_hist, fine_n_bin, test_size)
# Find the bin edges
bin_edge = fine_bin_edge[bin_id]
print("bin_edges:")
print(bin_edge)
# Check
bin_count = get_bin_count(bin_edge, x)
print("bin_counts:")
print(bin_count)
print("ideal count per bin:")
print(test_size * 1.0/n_bin)
Выход программы:
bin_edges:
[-1.86507282 -0.22751473 0.2085489 1.30798591 3.57180559 4.40218207
7.41287669]
bin_counts:
[1656 1675 1668 1663 1660 1677]
ideal count per bin:
1666.6666666666667
Проблема:
я не могу определить порог s, и ожидать, что отсчеты бин находятся в наиболее s%, отличное от идеального количества в бункере.
Какая разница вы готовы принять? Например, все размеры бункера должны быть в пределах 1 друг от друга, или 5, или 10, или 5%, или что? Вы не можете просто сортировать данные? –
Я думаю, что скоро засыпаю ... Я не могу сортировать данные, если вы хотите упорядочить все данные, потому что я предполагаю, что это будет означать чтение данных с жесткого диска много раз. И жесткий диск ужасно медленный. В основном, мне не нравится, что я не могу указать пороговое значение s и знаю, что bin_counts будет не более s%, отличным от идеального числа в ящике. Я хочу сделать это, потому что это означает, что я могу контролировать ошибку позже. Ошибка этого края бука умножается и нарастает. –
Три цитируемые статьи в [этом ответе] (http://stackoverflow.com/a/7659694/620908). –