Making a 10x10 grid from a list of arrays - python

I'm struggling to list my array as a 10x10 grid, the output I keep getting isn't what I'm looking for. I was hoping someone could help me out.
import numpy as np
x = 1
y = 1
scale = 10
nn = []
for x in range(1,scale+1):
mm = []
for y in range(1,scale+1):
xy = [x,y]
mm.append(xy)
#print(xy)
y=+1
nn.append(mm)
x=+1
nn
grid_array = np.array(nn)
grid=np.meshgrid(grid_array)
But the output I get isn't displaying 10x10
[array([ 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1,
9, 1, 10, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5, 2, 6, 2, 7,
2, 8, 2, 9, 2, 10, 3, 1, 3, 2, 3, 3, 3, 4, 3, 5, 3,
6, 3, 7, 3, 8, 3, 9, 3, 10, 4, 1, 4, 2, 4, 3, 4, 4,
4, 5, 4, 6, 4, 7, 4, 8, 4, 9, 4, 10, 5, 1, 5, 2, 5,
3, 5, 4, 5, 5, 5, 6, 5, 7, 5, 8, 5, 9, 5, 10, 6, 1,
6, 2, 6, 3, 6, 4, 6, 5, 6, 6, 6, 7, 6, 8, 6, 9, 6,
10, 7, 1, 7, 2, 7, 3, 7, 4, 7, 5, 7, 6, 7, 7, 7, 8,
7, 9, 7, 10, 8, 1, 8, 2, 8, 3, 8, 4, 8, 5, 8, 6, 8,
7, 8, 8, 8, 9, 8, 10, 9, 1, 9, 2, 9, 3, 9, 4, 9, 5,
9, 6, 9, 7, 9, 8, 9, 9, 9, 10, 10, 1, 10, 2, 10, 3, 10,
4, 10, 5, 10, 6, 10, 7, 10, 8, 10, 9, 10, 10])]
Edited.
This is what I have thus far, thanks for the help guys.
import numpy as np
scale = 10
array = np.empty(shape=(scale, scale, 2)).astype(int)
for x in range(1,scale+1):
for y in range(1,scale+1):
#print([x,y])
array[x-1,y-1] = [x,y]
print(array)

You can use numpy to do that. like this
np.reshape(arr, (-1,10))
See.
Convert a 1D array to a 2D array in numpy

It's pretty far from clear what you want to achieve, but if you simply want to know how to generate a 10x10 numpy array using two for loops, here is what you can do (not he most pythonic way to do it though):
import numpy as np
scale = 10
array = np.empty(shape=(scale, scale))
for x in range(scale):
for y in range(scale):
array[x,y] = 42 # replace with whatever dynamically assigned value you want there
print(array)

Related

Random function keeps generating a dtype

I'm trying to create a function that generates a dictionary. Dictionary will contain inputs element1 = user will decide input & element2 = is a rng.integers(low, high, size = 50). If I simulate code below, it will return the dictionary + dtype=64.
Question: How do I remove dtype=64, when I would like to keep it as an array?
emptydictionary = {}
element2 = rng.integers(1, 10, size = 50)
element1 = 5
def function(element1,element2):
emptydictionary.update({element1:element2})
return emptydictionary
function(element1,element2)
output is {5: array([5, 7, 5, 3, 7, 9, 3, 8, 3, 7, 8, 5, 7, 3, 1, 1, 5, 9, 2, 5, 7, 2, 7, 3, 8, 6, 5, 2, 5, 8, 1, 7, 5, 7, 6, 4, 3, 6, 2, 6, 1, 6, 6, 1, 7, 4, 8, 1, 2, 5], dtype=int64)}

Python: How to efficiently create all possible 2 element swaps of an array?

I try to generate all possible 2-element swaps of a given array.
For example:
candidate = [ 5, 9, 1, 8, 3, 7, 10, 6, 4, 2]
result = [[ 9, 5, 1, 8, 3, 7, 10, 6, 4, 2]
[ 1, 9, 5, 8, 3, 7, 10, 6, 4, 2]
[ 8, 9, 1, 5, 3, 7, 10, 6, 4, 2]
[ 3, 9, 1, 8, 5, 7, 10, 6, 4, 2]
[ 7, 9, 1, 8, 3, 5, 10, 6, 4, 2]
[10, 9, 1, 8, 3, 7, 5, 6, 4, 2]
[ 6, 9, 1, 8, 3, 7, 10, 5, 4, 2]
[ 4, 9, 1, 8, 3, 7, 10, 6, 5, 2]
[ 2, 9, 1, 8, 3, 7, 10, 6, 4, 5]
[ 5, 1, 9, 8, 3, 7, 10, 6, 4, 2]
[ 5, 8, 1, 9, 3, 7, 10, 6, 4, 2]
[ 5, 3, 1, 8, 9, 7, 10, 6, 4, 2]
[ 5, 7, 1, 8, 3, 9, 10, 6, 4, 2]
[ 5, 10, 1, 8, 3, 7, 9, 6, 4, 2]
[ 5, 6, 1, 8, 3, 7, 10, 9, 4, 2]
[ 5, 4, 1, 8, 3, 7, 10, 6, 9, 2]
[ 5, 2, 1, 8, 3, 7, 10, 6, 4, 9]
[ 5, 9, 8, 1, 3, 7, 10, 6, 4, 2]
[ 5, 9, 3, 8, 1, 7, 10, 6, 4, 2]
[ 5, 9, 7, 8, 3, 1, 10, 6, 4, 2]
[ 5, 9, 10, 8, 3, 7, 1, 6, 4, 2]
[ 5, 9, 6, 8, 3, 7, 10, 1, 4, 2]
[ 5, 9, 4, 8, 3, 7, 10, 6, 1, 2]
[ 5, 9, 2, 8, 3, 7, 10, 6, 4, 1]
[ 5, 9, 1, 3, 8, 7, 10, 6, 4, 2]
[ 5, 9, 1, 7, 3, 8, 10, 6, 4, 2]
[ 5, 9, 1, 10, 3, 7, 8, 6, 4, 2]
[ 5, 9, 1, 6, 3, 7, 10, 8, 4, 2]
[ 5, 9, 1, 4, 3, 7, 10, 6, 8, 2]
[ 5, 9, 1, 2, 3, 7, 10, 6, 4, 8]
[ 5, 9, 1, 8, 7, 3, 10, 6, 4, 2]
[ 5, 9, 1, 8, 10, 7, 3, 6, 4, 2]
[ 5, 9, 1, 8, 6, 7, 10, 3, 4, 2]
[ 5, 9, 1, 8, 4, 7, 10, 6, 3, 2]
[ 5, 9, 1, 8, 2, 7, 10, 6, 4, 3]
[ 5, 9, 1, 8, 3, 10, 7, 6, 4, 2]
[ 5, 9, 1, 8, 3, 6, 10, 7, 4, 2]
[ 5, 9, 1, 8, 3, 4, 10, 6, 7, 2]
[ 5, 9, 1, 8, 3, 2, 10, 6, 4, 7]
[ 5, 9, 1, 8, 3, 7, 6, 10, 4, 2]
[ 5, 9, 1, 8, 3, 7, 4, 6, 10, 2]
[ 5, 9, 1, 8, 3, 7, 2, 6, 4, 10]
[ 5, 9, 1, 8, 3, 7, 10, 4, 6, 2]
[ 5, 9, 1, 8, 3, 7, 10, 2, 4, 6]
[ 5, 9, 1, 8, 3, 7, 10, 6, 2, 4]]
I currently achive this by using two nested for-loops:
neighborhood = []
for node1 in range(candidate.size - 1):
for node2 in range(node1 + 1, candidate.size):
neighbor = np.copy(candidate)
neighbor[node1] = candidate[node2]
neighbor[node2] = candidate[node1]
neighborhood.append(neighbor)
The larger the array gets, the more inefficient and slower it becomes. Is there a more efficient way here that can also process arrays with three-digit contents?
Thank you!
You can use a generator if you need to use those arrays one by one (in this way, you don't need to memorize them all, you need very little space):
from itertools import combinations
def gen(lst):
for i, j in combinations(range(len(lst)), 2):
yield lst[:i] + lst[j] + lst[i:j] + lst[i] + lst[j:]
And then you can use it in this way:
for lst in gen(candidate):
# do something with your list with two swapped elements
This is going to save much space, but it's probably going to be still slow overall.
Here is a solution using NumPy. This is not space efficient (because it's memorizing all possible lists with swapped elements), but it might be much faster because of NumPy optimizations. Give it a try!
from itertools import combinations
from math import comb
arr = np.tile(candidate, (comb(len(candidate), 2), 1))
indices = np.array(list(combinations(range(len(candidate)), 2)))
arr[np.arange(arr.shape[0])[:, None], indices] = arr[np.arange(arr.shape[0])[:, None], np.flip(indices, axis=-1)]
Example (with candidate = [0, 1, 2, 3]):
>>> arr
array([[1, 0, 2, 3],
[2, 1, 0, 3],
[3, 1, 2, 0],
[0, 2, 1, 3],
[0, 3, 2, 1],
[0, 1, 3, 2]])
Notice that math.comb (which gives you the total number of possible lists with 2 swapped elements) is available only with python >= 3.8. Please have a look at this question to know how to replace math.comb in case you're using an older python version.
To swap only two items in any given list, I'd recommend using range with itertools.combinations. It is probably good to use a generator with the yield statement too, though if you are getting all results at once, it probably doesn't matter much.
from itertools import combinations
def swap2(l):
for pair in combinations(range(len(l)), 2):
l2 = l[:]
l2[pair[0]], l2[pair[1]] = l2[pair[1]], l2[pair[0]]
yield l2
if __name__ == "__main__":
candidate = [5, 9, 1, 8, 3, 7, 10, 6, 4, 2]
result = [l for l in swap2(candidate)]

Binning in Numpy

I have an array A which I am trying to put into 10 bins. Here is what I've done.
A = range(1,94)
hist = np.histogram(A, bins=10)
np.digitize(A, hist[1])
But the output has 11 bins, not 10, with the last value (93) placed in bin 11, when it should have been in bin 10. I can fix it with a hack, but what's the most elegant way of doing this? How do I tell digitize that the last bin in hist[1] is inclusive on the right - [ ] instead of [ )?
The output of np.histogram actually has 10 bins; the last (right-most) bin includes the greatest element because its right edge is inclusive (unlike for other bins).
The np.digitize method doesn't make such an exception (since its purpose is different) so the largest element(s) of the list get placed into an extra bin. To get the bin assignments that are consistent with histogram, just clamp the output of digitize by the number of bins, using fmin.
A = range(1,94)
bin_count = 10
hist = np.histogram(A, bins=bin_count)
np.fmin(np.digitize(A, hist[1]), bin_count)
Output:
array([ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4,
4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10])

numpy.unique gives non-unique output?

I am trying to get the indices of unique elements of a numpy array (long vector of 3628621 elements).
However, I must do something wrong, because when I try to select the unique elements I am still finding duplicates:
Vector
Out[165]: array([712450, 714390, 718560, ..., 384390, 992041, 94852])
Loc = np.where(np.unique(Vector)) # Find indices of unique elements
Vector_New = Vector[Loc] # Create new vector with all unique elements
np.where(Vector_New == 173020) # See how often/where '173020' exists
Out[166]: (array([ 7098, 11581], dtype=int64),)
So, the integer '173020' exists still twice in the new vector, although I expected that all elements should be unique. The new vector is 11594 elements long.
Thanks for the help!
Regards,
Timen
np.unique has several parameters that can be activated and will give you the needed information. It's calling signature is:
np.unique(ar, return_index=False, return_inverse=False, return_counts=False)
read the docs.
In [50]: keys
Out[50]:
array([1, 3, 5, 2, 0, 7, 4, 7, 7, 2, 7, 5, 5, 3, 6, 2, 3, 5, 5, 5, 6, 9, 6,
5, 2, 1, 6, 6, 5, 9, 9, 6, 5, 5, 9, 9, 6, 3, 7, 0, 5, 1, 7, 6, 2, 4,
1, 0, 6, 5, 4, 8, 8, 4, 2, 1, 8, 3, 1, 9, 8, 4, 4, 2, 4, 7, 2, 6, 8,
6, 5, 2, 4, 9, 1, 5, 3, 1, 5, 6, 2, 2, 8, 4, 0, 4, 9, 0, 8, 1, 5, 3,
1, 3, 7, 1, 5, 8, 5, 8])
In [51]: np.unique(keys, return_counts=True, return_index=True)
Out[51]:
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
array([ 4, 0, 3, 1, 6, 2, 14, 5, 51, 21], dtype=int32),
array([ 5, 11, 11, 8, 10, 18, 12, 8, 9, 8]))

How to make duplicates of values in a list python

Quick question... searched and didn't find anything. I have this list:
list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
I want to have each value repeated 3 more times in the same list... How do I do so? I tried some for loops that .append to the list but things got messy. I ended up getting some list in list that were in lists. I have a feeling .append is not right for this scenario.
In [1]: my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
In [2]: sorted(my_list * 3)
Note that you should not use list as a variable name, because it shadows the keyword list.
One other option is to use numpy:
In [8]: import numpy as np
In [9]: np.repeat(my_list, 3)
Use nested loops in a list comprehension.
>>> [x for x in L for y in range(4)]
[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
You can try something like this!
baselist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
[z for y in [[x]*4 for x in baselist] for z in y]
This is equivalent to:
listofLists = []
for x in baseList:
listofLists.append([x]*4)
finalList = []
for y in listofLists:
for z in y:
finalList.append(z)
You see, the list comprehension simply shortens the logic, but whether it's more readable will depend on your grasp of comprehension syntax.
You could do like this,
>>> lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
>>> [j for i in lst for j in [i,i,i,i]]
[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
Another itertools variation using the flatten recipe
>>> m = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
>>> import itertools
>>> list(itertools.chain.from_iterable(itertools.izip(m,m,m,m)))
[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
>>>

Categories

Resources