Can i change value of Adjacency Matrix on Python Programming? - python

I have problem with my code, i cannot print or change value of Adjacency matrix, can you help me sir?
i have code like this
for i in range(len(A.todense())):
for j in A[i].todense()*1:
print(j)
and the output is
[[0 0 0 0 0 1 1 0]]
[[0 0 0 0 0 0 0 1]]
[[0 0 0 0 0 1 0 0]]
[[0 0 0 0 0 1 0 0]]
[[0 0 0 0 0 0 0 1]]
[[1 0 1 1 0 0 1 0]]
[[1 0 0 0 0 1 0 0]]
[[0 1 0 0 1 0 0 0]]
and want to change zero to one, or one to zero, but i cannot print or change with A.todense()[i][j]. Can you help me to change the value of adjacency matrix? Thanks you
top up saldo paypal

You can't change value in Adjancency matrix, so that you have to convert to numpy or other array type that can change value.
One Solution Below
A = np.array(A.data)
for i in range(len(A)):
for j in range(len(A[i])):
if A[i][j] == 0:
A[i][j] = 1
else:
A[i][j] = 0
That will change values and then convert to Adjancency matrix.

Related

Fill the secondary diagonal with respect to a point?

The problem is that I have a point, say P = (p1,p2), in a 2x2 numpy array in Python. Now using the point P I want to fill the all the entries in the secondary diagonal passing through with that point.
So what it looks like is:
arr = [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]
P = (1,4)
arr = [0,0,0,0,0
0,0,0,0,1
0,0,0,1,0
0,0,1,0,0
0,1,0,0,0]
or let's say P = (3,0):
arr = [0,0,0,1,0
0,0,1,0,0
0,1,0,0,0
1,0,0,0,0
0,0,0,0,0]
The array with ones is the final result required.
You can slice the array using the indices and feed it to np.fliplr and p.fill_diagonal to get the reversed diagonal
arr = np.zeros(shape=(5, 5), dtype=int)
p = (...)
np.fill_diagonal(np.fliplr(arr[p[0]:, :p[1]+1]), 1)
print(arr)
Output
p = 1, 4
[[0 0 0 0 0]
[0 0 0 0 1]
[0 0 0 1 0]
[0 0 1 0 0]
[0 1 0 0 0]]
p = 0, 3
[[0 0 0 1 0]
[0 0 1 0 0]
[0 1 0 0 0]
[1 0 0 0 0]
[0 0 0 0 0]]

Numpy get secondary diagonal with offset=1 and change the values

I have this 6x6 matrix filled with 0s. I got the secondary diagonal in sec_diag. The thing I am trying to do is to change the values of above the sec_diag inside the matrix with the odds numbers from 9-1 [9,7,5,3,1]
import numpy as np
x = np.zeros((6,6), int)
sec_diag = np.diagonal(np.fliplr(x), offset=1)
The result should look like this:
[[0,0,0,0,9,0],
[0,0,0,7,0,0],
[0,0,5,0,0,0],
[0,3,0,0,0,0],
[1,0,0,0,0,0],
[0,0,0,0,0,0]]
EDIT: np.fill_diagonal isn't going to work.
You should use roll
x = np.zeros((6,6),dtype=np.int32)
np.fill_diagonal(np.fliplr(x), [9,7,5,3,1,0])
xr = np.roll(x,-1,axis=1)
print(xr)
Output
[[0 0 0 0 9 0]
[0 0 0 7 0 0]
[0 0 5 0 0 0]
[0 3 0 0 0 0]
[1 0 0 0 0 0]
[0 0 0 0 0 0]]
Maybe you should try with a double loop

Write functions resilient to variable dimension array

I'm struggling when writing a function that would seemlessly apply to any numpy arrays whatever its dimension.
At one point in my code, I have boolean arrays that I consider as mask for other arrays (0 = not passing, 1 = passing).
I would like to "enlarge" those mask arrays by overriding zeros adjacent to ones on a defined range.
Example :
input = [0,0,0,0,0,1,0,0,0,0,1,0,0,0]
enlarged_by_1 = [0,0,0,0,1,1,1,0,0,1,1,1,0,0]
enlarged_by_2 = [0,0,0,1,1,1,1,1,1,1,1,1,1,0]
input = [[0,0,0,1,0,0,1,0],
[0,1,0,0,0,0,0,0],
[0,0,0,0,0,0,1,0]]
enlarged_by_1 = [[0,0,1,1,1,1,1,1],
[1,1,1,0,0,0,0,0],
[0,0,0,0,0,1,1,1]]
This is pretty straighforward when inputs are 1D.
However, I would like this function to take seemlessy 1D, matrix, 3D, and so on.
So for a matrix, the same logic would be applied to each lines.
I read about ellipsis, but it does not seem to be applicable in my case.
Flattening the input applying the logic and reshaping the array would lead to possible contamination between individual arrays.
I do not want to go through testing the shape of input numpy array / recursive function as it does not seems very clean to me.
Would you have some suggestions ?
The operation that you are described seems very much like a convolution operation followed by clipping to ensure that values remain 0 or 1.
For your example input:
import numpy as np
input = np.array([0,0,0,0,0,1,0,0,0,0,1,0,0,0], dtype=int)
print(input)
def enlarge_ones(x, k):
mask = np.ones(2*k+1, dtype=int)
return np.clip(np.convolve(x, mask, mode='same'), 0, 1).astype(int)
print(enlarge_ones(input, k=1))
print(enlarge_ones(input, k=3))
which yields
[0 0 0 0 0 1 0 0 0 0 1 0 0 0]
[0 0 0 0 1 1 1 0 0 1 1 1 0 0]
[0 0 1 1 1 1 1 1 1 1 1 1 1 1]
numpy.convolve only works for 1-d arrays. However, one can imagine a for loop over the number of array dimensions and another for loop over each array. In other words, for a 2-d matrix first operate on every row and then on every column. You get the idea for nd-array with more dimensions. In other words the enlarge_ones would become something like:
def enlarge_ones(x, k):
n = len(x.shape)
if n == 1:
mask = np.ones(2*k+1, dtype=int)
return np.clip(np.convolve(x, mask, mode='same')[:len(x)], 0, 1).astype(int)
else:
x = x.copy()
for d in range(n):
for i in np.ndindex(x.shape[:-1]):
x[i] = enlarge_ones(x[i], k) # x[i] is 1-d
x = x.transpose(list(range(1, n)) + [0])
return x
Note the use of np.transpose to rotate the dimensions so that np.convolve is applied to the 1-d along each dimension. This is exactly n times, which returns the matrix to original shape at the end.
x = np.zeros((3, 5, 7), dtype=int)
x[1, 2, 2] = 1
print(x)
print(enlarge_ones(x, k=1))
[[[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 1 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 1 1 1 0 0 0]
[0 1 1 1 0 0 0]
[0 1 1 1 0 0 0]
[0 0 0 0 0 0 0]]
[[0 0 0 0 0 0 0]
[0 1 1 1 0 0 0]
[0 1 1 1 0 0 0]
[0 1 1 1 0 0 0]
[0 0 0 0 0 0 0]]
[[0 0 0 0 0 0 0]
[0 1 1 1 0 0 0]
[0 1 1 1 0 0 0]
[0 1 1 1 0 0 0]
[0 0 0 0 0 0 0]]]

How to create an NxM matrix with each column value in range(x,y)?

Problem:
I want to create a 5 dimensional numpy matrix, each column's value restricted to a range. I can't find any solution online for this problem.
I'm trying to generate a list of rules in the form
Rule: (wordIndex, row, col, dh, dv)
with each column having values in range ( (0-7), (0,11), (0,11), (-1,1), (-1,1) ). I want to generate all possible combinations.
I could easily make the matrix using five loops, one inside another
m, n = 12, 12
rules =[]
for wordIndex in range(0, 15):
for row in range(0,m):
for col in range(0,n):
for dh in range(-1,2):
for dv in range(-1,2):
rules.append([wordIndex, row, col, dh, dv])
But this approach takes an exponentially large time to do this and I wonder if there's a better, vectorized approach to solve this problem using numpy.
I've tried the following but none seem to work:
rules = np.mgrid[words[0]:words[-1], 0:11, 0:11, -1:1, -1:1]
rules = np.rollaxis(words,0,4)
rules = rules.reshape((len(words)*11*11*3*3, 5))
Another approach that fails:
values = list(itertools.product(len(wordsGiven()), range(11), range(11), range(-1,1), range(-1,1)))
I also tried np.arange() but can't seem to figure out how to use if for a multidimensional array.
I think there should be a better way for it. But just in case if you cannot find it, here is a hacky array based way for it:
shape = (8-0, 12-0, 12-0, 2-(-1), 2-(-1))
a = np.zeros(shape)
#create array of indices
a = np.argwhere(a==0).reshape(*shape, len(shape))
#correct the ranges that does not start from 0, here 4th and 5th elements (dh and dv) reduced by -1 (starting range).
#You can adjust this for any other ranges and elements easily.
a[:,:,:,:,:,3:5] -= 1
First few elements of a:
[[[[[[ 0 0 0 -1 -1]
[ 0 0 0 -1 0]
[ 0 0 0 -1 1]]
[[ 0 0 0 0 -1]
[ 0 0 0 0 0]
[ 0 0 0 0 1]]
[[ 0 0 0 1 -1]
[ 0 0 0 1 0]
[ 0 0 0 1 1]]]
[[[ 0 0 1 -1 -1]
[ 0 0 1 -1 0]
[ 0 0 1 -1 1]]
[[ 0 0 1 0 -1]
[ 0 0 1 0 0]
[ 0 0 1 0 1]]
[[ 0 0 1 1 -1]
[ 0 0 1 1 0]
[ 0 0 1 1 1]]]
[[[ 0 0 2 -1 -1]
[ 0 0 2 -1 0]
[ 0 0 2 -1 1]]
[[ 0 0 2 0 -1]
[ 0 0 2 0 0]
[ 0 0 2 0 1]]
[[ 0 0 2 1 -1]
[ 0 0 2 1 0]
[ 0 0 2 1 1]]]
...

counting objects using scikit-image label

My goal is to count objects in a binary array, using Python. I am applying the scikit-image measure.label, to to count objects(should be 1's) in the the array, despite reading the documentation-link, I am getting results that cannot be explained.
a=np.array(np.matrix('0 1 0 0 1;0 1 0 0 0; 0 0 0 0 0;0 0 0 0 1'))
print(a)
img=measure.label(a)
propsa = measure.regionprops(img)
length = len(propsa)
print ('length='+str(length))
for label in propsa:
print (label.centroid)
>>>
[[0 1 0 0 1]
[0 1 0 0 0]
[0 0 0 0 0]
[0 0 0 0 1]]
length=3
(0.5, 1.0)
(0.0, 4.0)
(3.0, 4.0)
When background is selected to be zero,
a=np.array(np.matrix('0 1 0 0 1;0 1 0 0 0; 0 0 0 0 0;0 0 0 0 1'))
print(a)
img=measure.label(a, background=0)
propsa = measure.regionprops(img)
length = len(propsa)
print ('length='+str(length))
for label in propsa:
print (label.centroid)
>>>
[[0 1 0 0 1]
[0 1 0 0 0]
[0 0 0 0 0]
[0 0 0 0 1]]
length=2
(0.0, 4.0)
(3.0, 4.0)
Why is there inconsistent? From my understanding the label function labels "0" as -1 background?!
Following question
It appears that measure.label of the CSV file example counts two objects a large one and its cavity. Sure enough when I inquiry the coordinates of the cavity of img I get a value of 2. Which means the cavity is the second object. Why is an aggregate of zeros counted as an object, and is there away around it?
length=2
(214.23444957510378, 505.25546156532539)
(238.77173913043478, 740.28260869565213)
>>> img[238,740]
2
>>>
For debug purposes it is useful to print the full labeled image. With background=0:
>>> print(img)
[[-1 0 -1 -1 1]
[-1 0 -1 -1 -1]
[-1 -1 -1 -1 -1]
[-1 -1 -1 -1 2]]
The background is correctly labeled as -1. But when you call regionprops on it, it only returns RegionProperties objects for labels 1 and 2 because, as stated in the docs for regionprops(),
label_image : (N, M) ndarray
Labeled input image. Labels with value 0 are ignored.
Therefore the first area that has label 0 is ignored.
When background is not specified, the 0-filled area is has the label 0 and therefore ignored by regionprops(), giving the output of the remaining three 1-filled regions:
>>> print(img)
[[0 1 0 0 2]
[0 1 0 0 0]
[0 0 0 0 0]
[0 0 0 0 3]]
Ok here is simple solution that struck me.
I can simply define background=0, and img=img+1.
The problem was, when label is applied on the matrix with a background=0 the 0 values are changed to -1 and if I have a group of ones they are reduced to 0.Therefore by adding a 1, I adjust the img object to background=0 and any group of numbers that is not 0 will be counted.
Here is an example of what I mean:
import matplotlib
matplotlib.use('Gtk3Agg')
import numpy as np
from skimage import filters, morphology, measure
np.set_printoptions(threshold=np.nan)
a=np.array(np.matrix('0 1 0 0 1;0 1 0 0 0; 0 0 0 0 0;0 0 0 1 1'))
print(a)
img=measure.label(a, background=0)
print('img=')
print (img)
#adjusting +1
img=img+1
print('img+1=')
print (img)
propsa = measure.regionprops(img)
length = len(propsa)
print ('length='+str(length))
for label in propsa:
print (label.centroid)
The code returns the following.
>>>
(4, 5)
[[0 1 0 0 1]
[0 1 0 0 0]
[0 0 0 0 0]
[0 0 0 1 1]]
img=
[[-1 0 -1 -1 1]
[-1 0 -1 -1 -1]
[-1 -1 -1 -1 -1]
[-1 -1 -1 2 2]]
img+1=
[[0 1 0 0 2]
[0 1 0 0 0]
[0 0 0 0 0]
[0 0 0 3 3]]
length=3
(0.5, 1.0)
(0.0, 4.0)
(3.0, 3.5)

Categories