繁体   English   中英

Python中有很多维度的直方图

[英]Histograms with a lot of dimensions in Python

我正在模拟一个随机多体系统,目前我需要从生成的数据中获取多维概率分布。 为此,我尝试使用np.histogramdd如下:

bins = np.linspace(start = -x_max, stop = x_max, num = n_bins)
hists = np.histogramdd(Data, bins = [bins] * dimensions, density = True)

但是,对于n_bins = 20dimensions = 5np.shape(Data) = (1000, 5) ,此代码已经产生 MemoryError (或引发有关某些数组太大的异常),这远低于目标值。 桶的数量随着维度的数量呈指数增长,因此很容易看出为什么会出现这些问题。 所以,问题是:如何在 Python 中生成、存储和使用大尺寸直方图? 有没有这方面的现有框架? 换别的东西更好吗?

编辑:MCEV 和错误代码示例。

x_max = 10 
n_bins = 20 
Data = np.random.uniform(-x_max, x_max, size=(1000, dimensions))

bins = np.linspace(start = -x_max, stop = x_max, num = n_bins)
hists = np.histogramdd(Data, bins = [bins] * dimensions, density = True)

放置dimensions = 7 ,我得到:

lib\site-packages\numpy\lib\histograms.py in histogramdd(sample, bins, range, normed, weights, density)
1066 # Compute the number of repetitions in xy and assign it to the
1067 # flattened histmat.
-> 1068  hist = np.bincount(xy, weights, minlength=nbin.prod())
MemoryError:

dimensions = 15

   1062     # Compute the sample indices in the flattened histogram matrix.
   1063     # This raises an error if the array is too large.
-> 1064     xy = np.ravel_multi_index(Ncount, nbin)
   1065 
   1066     # Compute the number of repetitions in xy and assign it to the

ValueError: invalid dims: array size defined by dims is larger than the maximum possible size. 

dimensions = 10

   1066     # Compute the number of repetitions in xy and assign it to the
   1067     # flattened histmat.
-> 1068     hist = np.bincount(xy, weights, minlength=nbin.prod())
   1069 
   1070     # Shape into a proper matrix

ValueError: 'minlength' must not be negative

如果直方图在每个轴上都有固定的 bin 宽度,您可以自己记账并使用低内存数据类型进行计数(例如每个 bin 1 个字节)。 在以下示例中,每个轴的 bin 都相同,但您可以针对沿轴不同的 bin 范围对其进行调整,只要 bin 边缘等距即可。

此代码不会进行范围检查; 您需要确保直方图箱足够宽以适合数据,否则您会收到错误消息。

import numpy as np

x_max = 10 
n_dim = 7
n_data = 100000
data = np.random.uniform(-x_max, x_max-0.01, size=(n_data, n_dim))

# assume bins are the same for all dimensions. Bin edges at x0+i*xstep.
n_bins = 5
x0 = -x_max
xstep = 2*x_max/n_bins

# high-dimensional histogram
hist = np.zeros((n_bins,)*n_dim, dtype=np.int8)

# build the histogram indices corresponding to the data samples.
ii = ((data - x0)*(1/xstep)).astype(np.int16) # shape (n_data, n_dim)

# increment the histogram bins. The np.add.at will correctly handle 
# bins that occur multiple times in the input.
np.add.at(hist, tuple(ii.T), 1)

但是在n_dim=89的情况下,无论如何你都会在大多数系统上用完 memory。

问题是你要如何处理一个有10**10 bin 的直方图; 你有 10**11 或更多的样品吗?

保留ii数组并在需要时生成低维直方图更实用。 例如,如果要将 7D 直方图简化为轴0, 1, 5, 6上的 4D 直方图:

hist_4d = np.zeros((n_bins,)*4, dtype=np.int16)
np.add.at(hist_4d, tuple(ii[:, [0, 1, 5, 6]].T), 1)

注意:我建议您对 bin 计数使用有符号整数。 Integer 溢出将保持沉默,但至少垃圾箱中的负数将表明您有溢出。

在第三种情况下,dims=10,由于溢出,您会收到错误。 此处添加了一个相关线程: 为什么 numpy.prod() 对于我的长自然数列表错误地返回负结果或 0? 这与 numpy.ndarray.prod() 特别相关。 您可以将产品计算切换回默认的 python 方式,而不是使用 numpy.ndarray.prod()。 但是,为此您必须编辑直方图 dd 的源代码

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM