jez - 6 months ago 37

Python Question

I have a large image

`A`

`B`

`numpy`

`A`

`B`

I've seen the discussion of

`numpy.take`

`numpy.roll`

wrapping around slices in Python / numpy and that shows me how to access and return a

`rowOffset`

`columnOffset`

`A = numpy.zeros((5,11), int)`

B = numpy.array([[1,2,3,4,5,6,7]]) * numpy.array([[10,100,1000]]).T

# OK, we wouldn't be able to fit more than one or two copies of B into A, but they demonstrate the wrapped placement problem

wrappedRowIndices = ( numpy.arange(B.shape[0]) + rowOffset ) % A.shape[0]

wrappedColumnIndices = ( numpy.arange(B.shape[1]) + columnOffset ) % A.shape[1]

A[ wrappedRowIndices, : ][ :, wrappedColumnIndices ] = B

I see from a comment on the question,

and from a moment's reflection on the way

`numpy`

`view`

Is there (Y) a way of assigning to wrapped slices of an array in this way, or (X) an existing utility for performing the kind of tessellation I'm trying to achieve?

Answer

`np.put`

is a 1d equivalent to `np.take`

:

```
In [1270]: A=np.arange(10)
In [1271]: np.take(A,[8,9,10,11],mode='wrapped')
Out[1271]: array([8, 9, 0, 1])
In [1272]: np.put(A,[8,9,10,11],[10,11,12,13],mode='wrapped')
In [1273]: A
Out[1273]: array([12, 13, 2, 3, 4, 5, 6, 7, 10, 11])
In [1274]: np.take(A,[8,9,10,11],mode='wrapped')
Out[1274]: array([10, 11, 12, 13])
```

Its docs suggest `np.place`

and `np.putmask`

(and `np.copyto`

). I haven't used those much, but it might be possible to construct a mask, and rearrangement of `B`

that would do the copy.

=================

Here's an experiment with `place`

:

```
In [1313]: A=np.arange(24).reshape(4,6)
In [1314]: mask=np.zeros(A.shape,bool)
In [1315]: mask[:3,:4]=True
In [1316]: B=-np.arange(12).reshape(3,4)
```

So I have `mask`

the same size as `A`

, with a 'hole' the size of `B`

.

I can roll both the `mask`

and `B`

, and `place`

the values in `A`

in a `wrapped`

fashion.

```
In [1317]: np.place(A, np.roll(mask,-2,0), np.roll(B,1,0).flat)
In [1318]: A
Out[1318]:
array([[ -8, -9, -10, -11, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[ 0, -1, -2, -3, 16, 17],
[ -4, -5, -6, -7, 22, 23]])
```

And with 2d rolls

```
In [1332]: m=np.roll(np.roll(mask,-2,0),-1,1)
In [1333]: m
Out[1333]:
array([[ True, True, True, False, False, True],
[False, False, False, False, False, False],
[ True, True, True, False, False, True],
[ True, True, True, False, False, True]], dtype=bool)
In [1334]: b=np.roll(np.roll(B,1,0),-1,1)
In [1335]: b
Out[1335]:
array([[ -9, -10, -11, -8],
[ -1, -2, -3, 0],
[ -5, -6, -7, -4]])
In [1336]: A=np.zeros((4,6),int)
In [1337]: np.place(A, m, b.flat)
In [1338]: A
Out[1338]:
array([[ -9, -10, -11, 0, 0, -8],
[ 0, 0, 0, 0, 0, 0],
[ -1, -2, -3, 0, 0, 0],
[ -5, -6, -7, 0, 0, -4]])
```