I want a numpy array like this:
b = np.array([[1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2],
[3, 3, 3, 3, 3, 3],
[4, 4, 4, 4, 4, 4],
[5, 5, 5, 5, 5, 5],
[6, 6, 6, 6, 6, 6],
[7, 7, 7, 7, 7, 7],
[8, 8, 8, 8, 8, 8],
[9, 9, 9, 9, 9, 9]])
Is there a faster way to create a NumPy array like this instead of typing them manually?
You can do something like this:
>>> np.repeat(np.arange(1, 10).reshape(-1,1), 6, axis=1)
array([[1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2],
[3, 3, 3, 3, 3, 3],
[4, 4, 4, 4, 4, 4],
[5, 5, 5, 5, 5, 5],
[6, 6, 6, 6, 6, 6],
[7, 7, 7, 7, 7, 7],
[8, 8, 8, 8, 8, 8],
[9, 9, 9, 9, 9, 9]])
Explanation:
np.arange(1, 10).reshape(-1,1) creates an array
array([[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9]])
np.repeat(_, 6, axis=1) repeats this 6 times on the first (or second in human words) axis.
Yes. There are plenty of methods. This is one:
np.repeat(np.arange(1,10),6,axis=0).reshape(9,6)
Another method is to use broadcasting:
>>> np.arange(1,10)[:,None] * np.ones(6, dtype=int)
array([[1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2],
[3, 3, 3, 3, 3, 3],
[4, 4, 4, 4, 4, 4],
[5, 5, 5, 5, 5, 5],
[6, 6, 6, 6, 6, 6],
[7, 7, 7, 7, 7, 7],
[8, 8, 8, 8, 8, 8],
[9, 9, 9, 9, 9, 9]])
For any w*l size, convert a list of lists into an np.array like so:
w = 6
l = 9
[np.array([[1+i]*w for i in range(d)])
array([[1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2],
[3, 3, 3, 3, 3, 3],
[4, 4, 4, 4, 4, 4],
[5, 5, 5, 5, 5, 5],
[6, 6, 6, 6, 6, 6],
[7, 7, 7, 7, 7, 7],
[8, 8, 8, 8, 8, 8],
[9, 9, 9, 9, 9, 9]])
np.transpose(np.array(([np.arange(1,10)] * 6)))
np.arange(1,10) creates an numpy array from 1 to 9.
[] puts the array into a list.
*6 augments the array 6 times.
np.array() converts the resulting structure (list of arrays) to a numpy array
np.transpose() rotates the orientation of the numpy array to get vertical one.
Related
This question already has answers here:
How to deep copy a list?
(10 answers)
Closed 1 year ago.
k=[
[7, 1, 3, 6, 8, 5, 5, 6, 4],
[7, 2, 6, 2, 2, 8, 3, 9, 6],
[3, 3, 8, 6, 1, 3, 4, 5, 9],
[4, 5, 9, 8, 6, 6, 1, 3, 4],
[2, 8, 1, 4, 8, 6, 9, 5, 1],
[4, 7, 8, 6, 1, 8, 5, 8, 4],
[6, 7, 6, 4, 8, 6, 6, 7, 2],
[9, 8, 6, 3, 8, 8, 5, 5, 9],
[9, 5, 7, 5, 1, 1, 8, 6, 5]
]
a=[]
c=0
def foo():
global a
global k
global c
a.append(k.copy())
print(a)
for i in range(9):
for j in range(9):
k[i][j]=1
print(a)
foo()
Expected Output:
[[[7, 1, 3, 6, 8, 5, 5, 6, 4], [7, 2, 6, 2, 2, 8, 3, 9, 6], [3, 3, 8, 6, 1, 3, 4, 5, 9], [4, 5, 9, 8, 6, 6, 1, 3, 4], [2, 8, 1, 4, 8, 6, 9, 5, 1], [4, 7, 8, 6, 1, 8, 5, 8, 4], [6, 7, 6, 4, 8, 6, 6, 7, 2], [9, 8, 6, 3, 8, 8, 5, 5, 9], [9, 5, 7, 5, 1, 1, 8, 6, 5]]]
[[[7, 1, 3, 6, 8, 5, 5, 6, 4], [7, 2, 6, 2, 2, 8, 3, 9, 6], [3, 3, 8, 6, 1, 3, 4, 5, 9], [4, 5, 9, 8, 6, 6, 1, 3, 4], [2, 8, 1, 4, 8, 6, 9, 5, 1], [4, 7, 8, 6, 1, 8, 5, 8, 4], [6, 7, 6, 4, 8, 6, 6, 7, 2], [9, 8, 6, 3, 8, 8, 5, 5, 9], [9, 5, 7, 5, 1, 1, 8, 6, 5]]]
Generated Output:
[[[7, 1, 3, 6, 8, 5, 5, 6, 4], [7, 2, 6, 2, 2, 8, 3, 9, 6], [3, 3, 8, 6, 1, 3, 4, 5, 9], [4, 5, 9, 8, 6, 6, 1, 3, 4], [2, 8, 1, 4, 8, 6, 9, 5, 1], [4, 7, 8, 6, 1, 8, 5, 8, 4], [6, 7, 6, 4, 8, 6, 6, 7, 2], [9, 8, 6, 3, 8, 8, 5, 5, 9], [9, 5, 7, 5, 1, 1, 8, 6, 5]]]
[[[1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1]]]
With copy() you perform a shallow copy.
You need a deep copy. See Docs for more information
The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):
A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.
from copy import deepcopy
a.append(deepcopy(k))
print(a)
for i in range(9):
for j in range(9):
k[i][j]=1
print(a)
.copy method of list is shallow, you need to use copy.deepcopy if you want to get totally independent copy, consider following example
import copy
k1 = [[1,2],[3,4]]
k2 = k1.copy()
k3 = copy.deepcopy(k1)
k1[0][0] = 0
print(k2)
print(k3)
output
[[0, 2], [3, 4]]
[[1, 2], [3, 4]]
Using .copy is fine if you are working with flat list of immutable objects, you have list of list which are mutable.
I want to do divide an 8*8 array in to 4 segments(each segment of 4*4 array) as shown below in step2. Then again divide each segment in to other small 4 subsegemnts(each subsegment of 2*2 array) and then find the mean of each subsegment and then find the stabbndard deviation of each segment using the 4 means of the 4 subsegments in it. So that finally I only have an array (2*2 array) ie with 1 standard deviation for 1 segment.
import numpy as np
from skimage.util.shape import view_as_blocks
arr=np.array([[1,2,3,4,5,6,7,8],[1,2,3,4,5,6,7,8],[1,2,3,4,5,6,7,8],[1,2,3,4,5,6,7,8],[1,2,3,4,5,6,7,8],[1,2,3,4,5,6,7,8],[1,2,3,4,5,6,7,8],[1,2,3,4,5,6,7,8]])
img= view_as_blocks(arr, block_shape=(4,4))
upto this I have tried but I was unable to go further in my requirement as I am completely new to python and numpy. Kindly, help me in achieve my requirement.
#step1-Array
array([[1, 2, 3, 4, 5, 6, 7, 8],
[1, 2, 3, 4, 5, 6, 7, 8],
[1, 2, 3, 4, 5, 6, 7, 8],
[1, 2, 3, 4, 5, 6, 7, 8],
[1, 2, 3, 4, 5, 6, 7, 8],
[1, 2, 3, 4, 5, 6, 7, 8],
[1, 2, 3, 4, 5, 6, 7, 8],
[1, 2, 3, 4, 5, 6, 7, 8]])
#step2-segments
array([[[[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4]],
[[5, 6, 7, 8],
[5, 6, 7, 8],
[5, 6, 7, 8],
[5, 6, 7, 8]]],
[[[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4]],
[[5, 6, 7, 8],
[5, 6, 7, 8],
[5, 6, 7, 8],
[5, 6, 7, 8]]]])
**more steps to go to get final output**
Expected Output
([[1.0, 1.0],
[1.0, 1.0]])
It can be done using a function view_as_blocks of skimage.util.shape.
I have this python3 code that merges my sub-list to a single list:
l=[[4, 5, 6], [10], [1, 2, 3], [10], [1, 2, 3], [10], [4, 5, 6], [1, 2, 3], [4, 5, 6], [4, 5, 6], [7, 8, 9], [1, 2, 3], [7, 8, 9], [1, 2, 3], [4, 5, 6], [7, 8, 9], [4, 5, 6], [10], [7, 8, 9], [7, 8, 9]]
import itertools
merged = list(itertools.chain(*l))
from collections import Iterable
def flatten(items):
"""Yield items from any nested iterable; see Reference."""
for x in items:
if isinstance(x, Iterable) and not
isinstance(x, (str, bytes)):
for sub_x in flatten(x):
yield sub_x
else:
yield x
merged = list(itertools.chain(*l))
merged
The Undesired Shape of the Output
Though the output produces what I want but the shape of the output is not what I want
the output comes out in vertical shape as shown bellow:
[4,
5,
6,
10,
1,
2,
3,
10,
1,
2,
3,
10,
4,
5,
6,
1,
2,
3,
4,
5,
6,
4,
5,
6,
7,
8,
9,
1,
2,
3,
7,
8,
9,
1,
2,
3,
4,
5,
6,
7,
8,
9,
4,
5,
6,
10,
7,
8,
9,
7,
8,
9]
The Desirable Shape of the Output as I Would Want It
I would rather want the output to come out horizontally as I present bellow:
[4, 5, 6, 10, 1, 2, 3, 10, 1, 2, 3, 10, 4, 5, 6, 1, 2, 3, 4, 5, 6, 4, 5, 6, 7, 8, 9, 1, 2, 3, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 4, 5, 6, 10, 7, 8, 9, 7, 8, 9]
Please help me out, I will not mind if there is a way to make this happen different from my code.
Instead just use list comprehention:
l=[[4, 5, 6], [10], [1, 2, 3], [10], [1, 2, 3], [10], [4, 5, 6], [1, 2, 3], [4, 5, 6], [4, 5, 6], [7, 8, 9], [1, 2, 3], [7, 8, 9], [1, 2, 3], [4, 5, 6], [7, 8, 9], [4, 5, 6], [10], [7, 8, 9], [7, 8, 9]]
new_l=[j for i in l for j in i]
print(new_l)
Output :
C:\Users\Desktop>py x.py
[4, 5, 6, 10, 1, 2, 3, 10, 1, 2, 3, 10, 4, 5, 6, 1, 2, 3, 4, 5, 6, 4, 5, 6, 7, 8, 9, 1, 2, 3, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 4, 5, 6, 10, 7, 8, 9, 7, 8, 9]
You can do it like this:
In [5]: for x in merged:
...: print(x, end=' ')
...:
4 5 6 10 1 2 3 10 1 2 3 10 4 5 6 1 2 3 4 5 6 4 5 6 7 8 9 1 2 3 7 8 9 1 2 3 4 5 6 7 8 9 4 5 6 10 7 8 9 7 8 9
from collections import Counter
import itertools
import operator
list1=[[4, 5, 6], [10], [1, 2, 3], [10], [1, 2, 3], [10], [4, 5, 6], [1, 2, 3], [4, 5, 6], [4, 5, 6], [7, 8, 9], [1, 2, 3], [7, 8, 9], [1, 2, 3], [4, 5, 6], [7, 8, 9], [4, 5, 6], [10], [7, 8, 9], [7, 8, 9]]
dd = [item for sublist in list1 for item in sublist]
print(dd) # method 1
out1 = reduce(operator.concat,list1)
print(out1) # method 2
merged1 = list(itertools.chain.from_iterable(list1))
print(merged1) # method 3
merged2 = list(itertools.chain(*list1))
print(merged2) # method 4
I have a very large 2D numpy array of m x n elements. For each row, I need to remove exactly one element. So for example from a 4x6 matrix I might need to delete [0, 1], [1, 4], [2, 3], and [3, 3] - I have this set of coordinates stored in a list. In the end, the matrix will ultimately shrink in width by 1.
Is there a standard way to do this using a mask? Ideally, I need this to be as performant as possible.
Here is a method that use ravel_multi_index() to calculate one-dim index, and then delete() the elements, and reshape back to two-dim array:
import numpy as np
n = 12
a = np.repeat(np.arange(10)[None, :], n, axis=0)
index = np.random.randint(0, 10, n)
ravel_index = np.ravel_multi_index((np.arange(n), index), a.shape)
np.delete(a, ravel_index).reshape(n, -1)
the index:
array([4, 6, 9, 0, 3, 5, 3, 8, 9, 8, 4, 4])
the result:
array([[0, 1, 2, 3, 4, 5, 6, 7, 9],
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[0, 1, 2, 3, 4, 5, 6, 8, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 9],
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 9],
[0, 1, 3, 4, 5, 6, 7, 8, 9],
[0, 1, 2, 3, 5, 6, 7, 8, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 8],
[0, 1, 2, 4, 5, 6, 7, 8, 9]])
How can you select only the columns of a 2-d numpy array that correspond to a conditional boolean vector?
Say you have a 10x10 matrix, generated by, say:
a = np.random.randint(0,1,(10,10))
a =
array([[4, 9, 1, 9, 5, 2, 1, 7, 6, 5],
[5, 4, 2, 4, 8, 1, 5, 5, 7, 5],
[3, 8, 7, 4, 3, 4, 8, 8, 8, 3],
[5, 4, 4, 4, 9, 6, 7, 1, 6, 8],
[8, 3, 2, 1, 7, 5, 8, 8, 4, 9],
[9, 5, 6, 8, 6, 8, 1, 4, 4, 5],
[5, 4, 3, 2, 8, 3, 2, 2, 8, 6],
[2, 5, 4, 5, 9, 7, 9, 2, 5, 6],
[4, 5, 9, 7, 3, 1, 5, 7, 4, 8],
[6, 1, 3, 8, 8, 3, 2, 6, 6, 7]])
and you want to cut out all the rows corresponding to a vector containing (True/False or 0/1), like, say:
b = np.random.randint(0,2,10)
b =
array([0, 1, 1, 0, 1, 0, 1, 1, 1, 1])
I spent some time trying to find the simple syntax to return only specified colummns in a numpy array in python 3 and finally have it figured out. There are a number of other threads which show more complicated ways to do this, so I thought I would put the simple solution here. This will be very obvious to more experienced python users, but for a beginner like me, it would have been useful.
The simplest way is:
new_matrix = a[:,b==1]
which yields:
new_matrix =
array([[9, 1, 5, 1, 7, 6, 5],
[4, 2, 8, 5, 5, 7, 5],
[8, 7, 3, 8, 8, 8, 3],
[4, 4, 9, 7, 1, 6, 8],
[3, 2, 7, 8, 8, 4, 9],
[5, 6, 6, 1, 4, 4, 5],
[4, 3, 8, 2, 2, 8, 6],
[5, 4, 9, 9, 2, 5, 6],
[5, 9, 3, 5, 7, 4, 8],
[1, 3, 8, 2, 6, 6, 7]])
This would have saved me a lot of time.