[Numpy-discussion] Recipe: extract a sub-array using given shape, centered on given position
Nicolas Rougier
Nicolas.Rougier@loria...
Wed Aug 19 15:45:49 CDT 2009
Hi,
I've coded a function that allows to extract a contiguous array from
another one using a given shape and centered on a given position. I
did not find an equivalent within numpy so I hope I did not miss it.
The only interest of the function is to guarantee that the resulting
sub-array will have the required shape. If some values are out of
bounds, result array is padded with a fill value. Hope it can be
useful to someone.
Nicolas
Code:
-----
import numpy
def extract(Z, shape, position, fill=numpy.NaN):
""" Extract a sub-array from Z using given shape and centered on
position.
If some part of the sub-array is out of Z bounds, result is
padded
with fill value.
**Parameters**
`Z` : array_like
Input array.
`shape` : tuple
Shape of the output array
`position` : tuple
Position within Z
`fill` : scalar
Fill value
**Returns**
`out` : array_like
Z slice with given shape and center
**Examples**
>>> Z = numpy.arange(0,16).reshape((4,4))
>>> extract(Z, shape=(3,3), position=(0,0))
[[ NaN NaN NaN]
[ NaN 0. 1.]
[ NaN 4. 5.]]
Schema:
+-----------+
| 0 0 0 | = extract (Z, shape=(3,3), position=(0,0))
| +---------------+
| 0 | 0 1 | 2 3 | = Z
| | | |
| 0 | 4 5 | 6 7 |
+---|-------+ |
| 8 9 10 11 |
| |
| 12 13 14 15 |
+---------------+
>>> Z = numpy.arange(0,16).reshape((4,4))
>>> extract(Z, shape=(3,3), position=(3,3))
[[ 10. 11. NaN]
[ 14. 15. NaN]
[ NaN NaN NaN]]
Schema:
+---------------+
| 0 1 2 3 | = Z
| |
| 4 5 6 7 |
| +-----------+
| 8 9 |10 11 | 0 | = extract (Z, shape=(3,3),
position=(3,3))
| | | |
| 12 13 |14 15 | 0 |
+---------------+ |
| 0 0 0 |
+-----------+
"""
# assert(len(position) == len(Z.shape))
# if len(shape) < len(Z.shape):
# shape = shape + Z.shape[len(Z.shape)-len(shape):]
R = numpy.ones(shape, dtype=Z.dtype)*fill
P = numpy.array(list(position)).astype(int)
Rs = numpy.array(list(R.shape)).astype(int)
Zs = numpy.array(list(Z.shape)).astype(int)
R_start = numpy.zeros((len(shape),)).astype(int)
R_stop = numpy.array(list(shape)).astype(int)
Z_start = (P-Rs//2)
Z_stop = (P+Rs//2)+Rs%2
R_start = (R_start - numpy.minimum(Z_start,0)).tolist()
Z_start = (numpy.maximum(Z_start,0)).tolist()
R_stop = (R_stop - numpy.maximum(Z_stop-Zs,0)).tolist()
Z_stop = (numpy.minimum(Z_stop,Zs)).tolist()
r = [slice(start,stop) for start,stop in zip(R_start,R_stop)]
z = [slice(start,stop) for start,stop in zip(Z_start,Z_stop)]
R[r] = Z[z]
return R
Z = numpy.arange(0,16).reshape((4,4))
print Z
print
print extract(Z, shape=(3,3), position=(0,0))
print
print extract(Z, shape=(3,3), position=(3,3))
More information about the NumPy-Discussion
mailing list