Stevan Nixon
Stevan Nixon

Reputation: 87

How to concatenate values in a column in an array

I'm trying to concatenate the values in the first column in pairs. This is better illustrated by the example

import numpy as np
m = np.array([[11,12,13],[21,22,23],[31,32,33],[41,42,43]])

array([[11, 12, 13],
       [21, 22, 23],
       [31, 32, 33],
       [41, 42, 43]])

required output

11 21
21 31
31 41

The array size is not fixed

It is possible?

Upvotes: 1

Views: 82

Answers (3)

Pablo C
Pablo C

Reputation: 4761

You can use numpy indexing:

m[[np.arange(3),np.arange(1,4)],0].T

or numpy.hstack

np.hstack([m[:3,0, np.newaxis], m[1:4,0,np.newaxis]])

Both give:

array([[11, 21],
       [21, 31],
       [31, 41]])

Upvotes: 1

Mad Physicist
Mad Physicist

Reputation: 114320

The simple answer is to stack the elements you care about:

np.stack((m[:-1, 0], m[1:, 0]), axis=-1)

The more complex solution is to make a view into the data:

np.lib.stride_tricks.as_strided(m[:, 0], shape=(m.shape[0] - 1, 2), strides=(m.strides[0], m.strides[0]))

The first solution is straightforward and robust, but creates a copy of the data. The second solution creates a view into the original array. If you modify the view, you will see changes in the original array.

Upvotes: 2

ddejohn
ddejohn

Reputation: 8962

I believe you meant 11 21, in which case here's one solution:

>>> np.array([*zip(m[:,0], m[1:,0])])
array([[11, 21],
       [21, 31],
       [31, 41]])

To make it more general:

>>> c = 0
>>> np.array([*zip(m[:, c], m[1:, c])])
array([[11, 21],
       [21, 31],
       [31, 41]])

To explain: zip exhausts with the shortest iterable given. You can create overlapping pairs of a sequence quite easily then by simply zipping the sequence with an offset slice:

>>> x = [*range(10)]
>>> x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [*zip(x, x[1:])]
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9)]

Upvotes: 1

Related Questions