簡體   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