簡體   English   中英

將 256x256x256 numpy 陣列調整為 64x64x64 numpy 陣列。 我正在嘗試實現 4 的 window 大小來平均元素

[英]Resize 256x256x256 numpy array into 64x64x64 numpy array. I am trying to implement a window size of 4 to average the elements

我有一個稀疏的 3D NumPy 數組(256x256x256),我想通過使用移動的 Z05B8C74CBD96FBF2DE4C1A35Z702 平均值將其大小調整為 64x64x64。 解決這個問題的最干凈的方法是什么? 我是否應該考慮使用平均 window 為 4x4x4 的 3D 來解決問題?

我從一維 window 開始,如下所示,但我應該如何有效地擴展到二維或 3D?

def avgWindow(arr, size):
    return (arr[(n-1):] + arr[:-(n-1)])/float(size)

如果您想將數據合並為更粗略的分辨率,請嘗試使用np.reshapenp.mean沿每個維度進行:

A = np.array([.....])
s = A.shape  # (256, 256, 256)
B = A.copy()  # be sure to save original data

# reshape last dimension into new dim and bin-size (int div for index & shape)
B = B.reshape(s[0], s[1], s[2] // 4, 4)
B = np.mean(B, axis=-1)  # computes average along last dim
B.shape # (256, 256, 64)
... # repeat for other 2 dimensions.

這應該是合理的快,因為您使用的是numpys內部矢量化。

添加:

我不是稀疏矩陣的專家,但如果它真的是稀疏矩陣,那么看看scipy.sparse可能會很有用。

您正在尋找僅在大小為 (4,4,4) 的非重疊子矩陣上的卷積。 這是你如何做到的(可能是最快和最少的 memory 密集型,因為它共享 memory 並且不對任何不必要的子陣列進行額外計算):

from skimage.util.shape import view_as_windows
kernel = np.ones((4,4,4))
sub_matrices = view_as_windows(arr, kernel.shape, kernel.shape)
#Do convolution on extracted non-overlapping sub-matrices of shape (4,4,4)
output = np.einsum('ijk,mnlijk->mnl',kernel,sub_matrices)

If you do not wish to magnify the output to sum of points in kernel, simply divide the output by kernel.size (ie output/=kernel.size )

例子:

arr=np.ones((256,256,256))

output.形狀:

(64, 64, 64)

您可以使用scipy.signal.convolve來計算移動平均值,並跳過中間元素:

import numpy as np
from scipy.signal import convolve

old_shape = 256
a = np.arange(old_shape**3).reshape(old_shape, old_shape, old_shape)
new_shape = 64 # should be an integer divider of old shape
ksize = old_shape // new_shape
kernel = np.ones((ksize, ksize, ksize)) / (ksize**3)
res = convolve(a, kernel, 'valid')[::ksize,::ksize,::ksize]

我認為您可以成功使用池化機制,例如 tensorflow 提供的tensorflow (在我的情況下為 2.1 版本),看看tf池 ZC1C425268E683854F1AB5074C17A 這樣,在大小為(4,4,4)的 window 中,您可以取最大值或平均值。

一個例子(注意你應該重塑你的輸入矩陣添加一個 0 軸維度):

@tf.function
def get_local_maxima(X):
    #X has shape (1, 256,256,256)
    out = tf.nn.pool(X, window_shape=(4,4,4), pooling_type='MAX', padding='VALID') 
    return out

請注意,您可以將pooling_type更改為'AVG' ,以便在 window 中應用平均值。 output 將具有形狀(1, 64,64,64) ,因此您必須再次整形為 3D 矩陣,您可以簡單地使用:

out = tf.squeeze(out)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM