Insert values in 2d numpy array - arrays

I am stuck on this simple issue but I can't seem to figure it out, I have a diagonal array:
N = [1,2,3,4,5,6,7,8,9]
A = numpy.diag(N)
And I have a list of row and column indices such as this:
B = [[1,0],[2,1],[3,2]]
I want to insert a value of 1 in A given the location from B, it helps to think of A as a 2-D matrix and B the set of coordinates I want to insert the value A in.
I tried to use the numpy.put but it doesn't seem to allow me to access a 2d array and I don't know how to think about it in a for-loop sense.
The desired answer would look like this:
A = [[1,0,0,0,0,0,0,0,0],[1,2,0,0,0,0,0,0,0],[0,1,3,0,0,0,0,0,0],[0,0,0,4,0,0,0,0,0],...,[0,0,0,0,0,0,0,0,9]]
Any help is appreciated

Maybe for loop
for x in B:
A[x[0],x[1]]=1
A
Out[189]:
array([[1, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 2, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 3, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 4, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 5, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 6, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 7, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 8, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 9]])

You need to group the first and the second coordinates together:
I, J = zip(*B)
or
I, J = numpy.transpose(B)
Then you can index A directly
A[I, J] = 1

Make B a numpy array:
B = np.array(b)
Then just index using the first and second columns:
A[B[:, 0], B[:, 1]] = 1
array([[1, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 2, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 3, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 4, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 5, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 6, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 7, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 8, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 9]])

Related

Split 16x16 matrix in 4x4 in the same matrix

Hi guys I am doing a small exercise splitting a 16x16 matrix in 4x4 chunks, creating a sort of diagonal of small matrix. I am representing the 4x4 matrix with a value of 1 and the rest with a value of 0, painting them in the big matrix itself.
This what it should look like:
"1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0"
"1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0"
"1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0"
"1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0"
"0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1"
"0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1"
"0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1"
"0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1"
"1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0"
"1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0"
"1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0"
"1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0"
"0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1"
"0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1"
"0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1"
"0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1"
This is what I have achieved at me moment:
The red squares is what I am missing. These 4x4 matrix has to be "1" as well.
This is code (it is in javascript but I don't really care about the language).
let m = Array(16)
.fill("0")
.map(() => Array(16).fill("0"));
for (let i = 0; i < m.length; i++) {
for (let j = 0; j < m.length; j++) {
if (i % 8 < 4 && j % 8 < 4) {
m[i][j] = "1";
}
}
}
m.map((a) => console.log(JSON.stringify(a + "")));
Anyone know how to solve this problem? Thank You in advance!
I'd try something like that: it uses even/odd comparison to determine position for "1"
let m = Array(16)
.fill("")
.map(() => Array(16).fill(""));
for (let i = 0; i < m.length; i++) {
for (let j = 0; j < m.length; j++) {
let mi = parseInt(i/4);
let mj = parseInt(j/4);
m[i][j] = ((mi&1) == (mj&1))?"1":"0";
}
}
m.map((a) => console.log(JSON.stringify(a + "")));
In Ruby:
require 'matrix'
m = Matrix.build(16, 16) { |i,j| (i/4).even? == (j/4).even? ? 1 : 0 }
To convert the matrix object to an array:
m.to_a
#=> [[1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
# [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
# [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
# [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
# [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1],
# [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1],
# [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1],
# [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1],
# [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
# [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
# [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
# [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
# [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1],
# [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1],
# [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1],
# [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]]
See Matrix::build and Enumerable#to_a.
This should translate easily to other languages that have a matrix library, but even if such a library is not available, the clause
(i/4).even? == (j/4).even? ? 1 : 0
shows how the array can be constructed in an economic way.
Here's another way that does not use matrices.
a1 = [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0]
a2 = a1.reverse
#=> [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]
Array.new(16) { |i| ((i/4).even? ? a1 : a2).dup }
See Array::new and Kernel#dup.

Finding distance between every point in a matrix

def create_zero_matrix(n,m):
return [[0 for i in range(m)] for j in range(n)]
def m_tight_print(m):
for i in range(len(m)):
line = ''
for j in range(len(m[0])):
line += str(m[i][j])
print(line)
def pd_map(r,c,sites):
blank = create_zero_matrix(r,c)
for count, site in enumerate(sites):
blank[site[0]][site[1]] = count #locating the shops
Hello, how do I calculate the distance of every point in my matrix from a specific point such as [1,3] (point 0) or [4,7] (point 1) or [7,2] (point 2) and change that particular value such that it shows the point that is closest to that particular coordinate?
>>> pprint(pizzaMap)
[[0, 0, 0, 0, 0, 0, 0, 'X', 1, 1]
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1]
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1]
[0, 0, 0, 0, 0, 0, 'X', 1, 1, 1]
['X', 0, 0, 0, 0, 0, 1, 1, 1, 1]
[2, 2, 2, 2, 2, 'X', 1, 1, 1, 1]
[2, 2, 2, 2, 2, 2, 1, 1, 1, 1]
[2, 2, 2, 2, 2, 2, 2, 1, 1, 1]
[2, 2, 2, 2, 2, 2, 2, 1, 1, 1]
[2, 2, 2, 2, 2, 2, 2, 'X', 1, 1]]
This above is the test case but I can only get this from my code.
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 2, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
```.
I tried to use numpy.argwhere() but in the end I could not do it. What code must I use such that I am able to get my test case?

Stack vertically 5 2D-arrays in diagonal to build a whole 2d-array

l have 5 adjacency matrices (nump arrays) : A, B, C, D, E. each of dimension [20,20].
Given A, B, C, D, E, l would like to build F which stacks the 5 adjacency matrices. Since we have 5 2D arrays of [20,20] then F is of dimension [20*5,20*5] as follow :
F=np.zeros((100,100))
F=[
[A,0,0,0,...,0],
[0,...,B,...,0],
[0,...,..,C,0],
[0,.........D,..,0],
[0,...........,E],
]
such that :
A is indexed at F[0][:20]
B is indexed at F[1][20:40]
C is indexed at F[2][40:60]
D is indexed at F[3][60:80]
E is indexed at F[4][80:100]
What is the efficient numpy way to do that for larage number of adjacency matrices ?. Let's, we have n adjacency matrices to stack in a diagonal of new 2D array of [n*20,n*20]
You could use scipy.sparse.block_diag:
>>> AtoE = np.add.outer(np.arange(5, 10), np.zeros((3, 3), int))
>>> scipy.sparse.block_diag(AtoE).A
array([[5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9]], dtype=int64)
Sparse storage may be a good idea, anyway.
Alternatively, here is a more direct method in case you definitely want to use dense arrays:
>>> A = AtoE[0]
>>> N, N = A.shape
>>> k = len(AtoE)
>>> out = np.zeros((k, N, k, N), A.dtype)
>>> np.einsum('ijik->ijk', out)[...] = AtoE
>>> out.reshape(k*N, k*N)
array([[5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9]])

How to find the number of elements of a two-dimensional array, read from a file?

I have a file. Inside the file I have stored a two-dimensional array, something like this:
[[0, 0, 1, 0, 1, 0, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0, 1, 1, 0, 0], [0, 0, 0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0], [0, 1, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 1, 1, 0], [0, 1, 1, 0, 1, 0, 1, 0, 1, 0], [0, 1, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 1, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
Lengths of arrays can vary and they are not always 10 elements long.
I read the array from the file using this method:
map = IO.readlines("test.txt")
and when i print the result using:
map.each {|x| puts "#{x}"}
the output is what I expect it to be. But if I try to get the row length using:
puts map[0].length
I get 320 instead of 10 (which is what I expect).
Can someone explain me why am I getting 320 instead of 10 ?
Instead of IO#readlines you should use JSON#parse since it’s a valid json:
require 'json'
JSON.parse(File.read("test.txt"))
#⇒ [[0, 0, 1, 0, 1, 0, 1, 0, 1, 0],
# [0, 0, 0, 0, 0, 0, 1, 1, 0, 0],
# [0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
# [0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
# [0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 1, 1, 1, 0],
# [0, 1, 1, 0, 1, 0, 1, 0, 1, 0],
# [0, 1, 0, 0, 0, 0, 0, 1, 0, 0],
# [0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

NumPy Array: Minesweeper - substituting random items

I am at the beginning of an attempt to make a "minesweeper" game. I have an 8 x 8 array of 0's. I would like to substitute 8 random 0's within the array with the value 1 (to represent "mines"). I have no clue where to begin. Here is my code:
import numpy as np
import sys
import random
a = np.array([(0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0)])
for random.item in a:
item.replace(1)
print(a)
row = int(input("row "))
column = int(input("column "))
print(a[row - 1, column - 1])
How do I replace 8 random 0's within the array with 1's?
Use np.random.choice without replacement option -
In [3]: a # input array of all zeros
Out[3]:
array([[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]])
# Generate unique flattened indices and on a flattened view of
# input array assign those as 1s
In [8]: a.flat[np.random.choice(a.size,8,replace=False)] = 1
# Verify results
In [9]: a
Out[9]:
array([[0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]])

Resources