Transpose and unpack?
a, b = foo().T
>>> a, b = np.arange(20).reshape(-1, 2).T
>>> a
array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
>>> b
array([ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19])
Answer from Moses Koledoye on Stack OverflowTranspose and unpack?
a, b = foo().T
>>> a, b = np.arange(20).reshape(-1, 2).T
>>> a
array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
>>> b
array([ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19])
The zip(*...) idiom transposes a traditional more-dimensional Python list:
x = [[1,2], [3,4], [5,6]]
# get columns
a, b = zip(*x) # zip(*foo())
# a, b = map(list, zip(*x)) # if you prefer lists over tuples
a
# (1, 3, 5)
# get rows
a, b, c = x
a
# [1, 2]
How to split a 2d array into multiple 1d arrays?
Split a 2d NumPy array into 2 separate 2d arrays based on a column value
Splitting a 2 dimensional array or a list into two 1 dimensional lists in python - Stack Overflow
Python: how to split 2d array into many small - Stack Overflow
There was another question a couple of months ago which clued me in to the idea of using reshape and swapaxes. The h//nrows makes sense since this keeps the first block's rows together. It also makes sense that you'll need nrows and ncols to be part of the shape. -1 tells reshape to fill in whatever number is necessary to make the reshape valid. Armed with the form of the solution, I just tried things until I found the formula that works.
You should be able to break your array into "blocks" using some combination of reshape and swapaxes:
def blockshaped(arr, nrows, ncols):
"""
Return an array of shape (n, nrows, ncols) where
n * nrows * ncols = arr.size
If arr is a 2D array, the returned array should look like n subblocks with
each subblock preserving the "physical" layout of arr.
"""
h, w = arr.shape
assert h % nrows == 0, f"{h} rows is not evenly divisible by {nrows}"
assert w % ncols == 0, f"{w} cols is not evenly divisible by {ncols}"
return (arr.reshape(h//nrows, nrows, -1, ncols)
.swapaxes(1,2)
.reshape(-1, nrows, ncols))
turns c
np.random.seed(365)
c = np.arange(24).reshape((4, 6))
print(c)
[out]:
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
into
print(blockshaped(c, 2, 3))
[out]:
[[[ 0 1 2]
[ 6 7 8]]
[[ 3 4 5]
[ 9 10 11]]
[[12 13 14]
[18 19 20]]
[[15 16 17]
[21 22 23]]]
I've posted an inverse function, unblockshaped, here, and an N-dimensional generalization here. The generalization gives a little more insight into the reasoning behind this algorithm.
Note that there is also superbatfish's
blockwise_view. It arranges the
blocks in a different format (using more axes) but it has the advantage of (1)
always returning a view and (2) being capable of handling arrays of any
dimension.
It seems to me that this is a task for numpy.split or some variant.
e.g.
a = np.arange(30).reshape([5,6]) #a.shape = (5,6)
a1 = np.split(a,3,axis=1)
#'a1' is a list of 3 arrays of shape (5,2)
a2 = np.split(a, [2,4])
#'a2' is a list of three arrays of shape (2,5), (2,5), (1,5)
If you have a NxN image you can create, e.g., a list of 2 NxN/2 subimages, and then divide them along the other axis.
numpy.hsplit and numpy.vsplit are also available.
Or additionally, rearrange a 2d array so that it is in the form of a grid, so the first group of data in the array is in the first row, and the second in the second etc.
So I have this 2d array that looks something like this
[[1,2,4],[1,4,4],[2,2,4],[2,5,9]]
The first column in this array can only ever be a 1 or a 2, I want to split this 2d array into 2 smaller 2d arrays, with all the arrays where the first column equals 1 are in and another where all the arrays whos column 1 has 2 in it. I am new to numpy and have seen some examples and documents online but i can't seem to get exactly what I want. Here is the current code I am trying to use
```
np.split(trainingData, np.where(trainingData[:, 0]== 1.)[0][1:])
```
I am basically trying to split the trainingData(which is my array) into 2 separate arrays, but when I run this I get more than 2 arrays. If someone could point me on the right path that would be great!
Thank you
It is the ideal case of using zip as:
>>> x = [[1,2],[3,4],[5,6],[7,8],[9,10],[11,12],[13,14],[15,16],[17,18]]
# v unpack `x` list
>>> zip(*x)
[(1, 3, 5, 7, 9, 11, 13, 15, 17), (2, 4, 6, 8, 10, 12, 14, 16, 18)]
Returned value is a list of two tuples. In order to save each tuple in variable, you may do:
>>> a, b = zip(*x)
x_1 = [i[0] for i in x]
x_2 = [i[1] for i in x]
You're probably looking for something like numpy.reshape.
In your example:
numpy.array([[1,2,3,4], [5,6,7,8]]).reshape(2,4)
>>>array([[1,2], [3,4], [5,6], [7,8]])
Or, as suggested by @MSeifert, using -1 as final dimension will let numpy do the division by itself:
numpy.array([[1,2,3,4], [5,6,7,8]]).reshape(2,-1)
>>>array([[1,2], [3,4], [5,6], [7,8]])
To get your desired output, you need to reshape to a 3D array and then unpack the first dimension:
>>> inp = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])
>>> list(inp.reshape(-1, 2, 2))
[array([[1, 2],
[3, 4]]),
array([[5, 6],
[7, 8]]),
array([[ 9, 10],
[11, 12]]),
array([[13, 14],
[15, 16]])]
You can also unpack using = if you want to store the arrays in different variables instead of in one list of arrays:
>>> out1, out2, out3, out4 = inp.reshape(-1, 2, 2)
>>> out1
array([[1, 2],
[3, 4]])
If you're okay with a 3D array containing your 2D 2x2 arrays you don't need unpacking or the list() call:
>>> inp.reshape(-1, 2, 2)
array([[[ 1, 2],
[ 3, 4]],
[[ 5, 6],
[ 7, 8]],
[[ 9, 10],
[11, 12]],
[[13, 14],
[15, 16]]])
The -1 is a special value for reshape. As the documentation states:
One shape dimension can be -1. In this case, the value is inferred from the length of the array and remaining dimensions.
If you want it more general, just take the square root of the row-length and use that as argument for reshape:
>>> inp = np.ones((8, 8)) # 8x8 array
>>> square_shape = 2
>>> inp.reshape(-1, square_shape, square_shape) # 16 2x2 arrays
>>> square_shape = 4
>>> inp.reshape(-1, square_shape, square_shape) # 4 4x4 arrays
The function split() will split one string into one list. You can't make it produce two dimensions by passing it two parameters instead of one.
But you can call it twice, once for each delimiter:
>>> text = "536924636,www.microsoft.com,http://www.microsoft.com/pkiops/crl/MicW;536924733,www.microsoft.com,http://www.microsoft.com/pkiops/certs/Mi;536925898,crl.microsoft.com,http://crl.microsoft.com/pki/crl/product;"
>>> [r.split(",") for r in [r for r in text.split(";")]]
[
['536924636', 'www.microsoft.com', 'http://www.microsoft.com/pkiops/crl/MicW'],
['536924733', 'www.microsoft.com', 'http://www.microsoft.com/pkiops/certs/Mi'],
['536925898', 'crl.microsoft.com', 'http://crl.microsoft.com/pki/crl/product'],
['']
]
x = str(input())
arr = x.split(";")
finalArr = []
for items in arr:
arr2 = []
arr2.append(items)
finalArr.append(arr2)
print(finalArr)
Try this out. I am hoping this is what you are looking for.