Are there any convenience utilities for doing blockwise operations on Numpy arrays?
I am thinking of operations like Ising spin renormalization where you divide a matrix into blocks and return matrix where each block is replaced by its sum, average or other function.
Numpy with Python Input arrays for performing arithmetic operations such as add(), subtract(), multiply(), and divide() must be either of the same shape or should conform to array broadcasting rules.
column_stack() function is used to stack 1-D arrays as columns into a 2-D array.It takes a sequence of 1-D arrays and stack them as columns to make a single 2-D array. 2-D arrays are stacked as-is, just like with hstack function.
NumPy is fast because it can do all its calculations without calling back into Python. Since this function involves looping in Python, we lose all the performance benefits of using NumPy. For a 10,000,000-entry NumPy array, this functions takes 2.5 seconds to run on my computer.
__array_interface__ A dictionary of items (3 required and 5 optional). The optional keys in the dictionary have implied defaults if they are not provided. The keys are: shape (required) Tuple whose elements are the array size in each dimension.
You might be looking for superbatfish's blockwise_view
. This uses np.lib.stride_tricks.as_strided
to create a view of the array which places "blocks" of the array in their own axes.
For example, suppose you have a 2D array such as,
In [97]: arr = np.arange(24).reshape(6, 4)
In [98]: arr.shape
Out[98]: (6, 4)
In [99]: arr
Out[99]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])
and you wish to "chop it" into 4 blocks of shape (3, 2). You could use
blockwise_view
to convert it into a 4D array of shape (4, 3, 2):
In [34]: blocked = blockwise_view(arr, (3, 2)); blocked
Out[34]:
array([[[[ 0, 1],
[ 4, 5],
[ 8, 9]],
[[ 2, 3],
[ 6, 7],
[10, 11]]],
[[[12, 13],
[16, 17],
[20, 21]],
[[14, 15],
[18, 19],
[22, 23]]]])
In [37]: blocked.shape
Out[37]: (2, 2, 3, 2)
Now you could reshape it so all the values from one block are in the last axis:
In [41]: reshaped = blocked.reshape(-1, 3*2); reshaped
Out[41]:
array([[ 0, 1, 4, 5, 8, 9],
[ 2, 3, 6, 7, 10, 11],
[12, 13, 16, 17, 20, 21],
[14, 15, 18, 19, 22, 23]])
Now you can sum along that axis, or take its mean or apply some other function to the elements of each block:
In [103]: reshaped.sum(axis=-1)
Out[103]: array([ 27, 39, 99, 111])
In [104]: reshaped.mean(axis=-1)
Out[104]: array([ 4.5, 6.5, 16.5, 18.5])
Unlike my first answer, which can only be applied to 2D arrays,
blockwise_view
can be applied to arbitrary N-dimensional arrays. It returns a
2N-dimensional array where the first N axes index the blocks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With