i created a numpy array of size 10 by 10 with
x = np.eye(10, dtype=np.uint8)
[[1 0 0 0 0 0 0 0 0 0]
[0 1 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 0 0 0 0]
[0 0 0 1 0 0 0 0 0 0]
[0 0 0 0 1 0 0 0 0 0]
[0 0 0 0 0 1 0 0 0 0]
[0 0 0 0 0 0 1 0 0 0]
[0 0 0 0 0 0 0 1 0 0]
[0 0 0 0 0 0 0 0 1 0]
[0 0 0 0 0 0 0 0 0 1]]
then i created a images out of it using fromarray method in pillow lib
im = Image.fromarray(x, mode='1')
im.show()
but the image is completely wrong. Then i converted the image to numpy array
img_arr = np.array(im, dtype=np.uint8)
it looks like this
[[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 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]]
the array is completely wrong.There are no diagonal 1's.
Can some help me ?
complete code
import numpy as np
from PIL import Image, ImageOps
x = np.eye(10, dtype=np.uint8)
print(x)
im = Image.fromarray(x, mode='1')
im.show()
im.save("D:\Desktop/fig.jpeg")
print(im.mode)
img_arr = np.array(im, dtype=np.uint8)
print(img_arr)
Do not use "1". Use "L"
im = Image.fromarray(x, mode='L')
if you really want to use mode "1", you have to encode in bytes. Every bit on each byte is a pixel.
import matplotlib.pyplot as plt
x=np.array(bytes([128,64,32,16,8,4,2,1]))
im = Image.frombytes(data=x, mode='1',size=(8,8))
plt.imshow(im)
plt.show()
x=np.array([0b00010000,
0b00101000,
0b00010000,
0b11111110,
0b00010000,
0b00101000,
0b01000100,
0b01000100],dtype=np.uint8)
im = Image.frombytes(data=x, mode='1',size=(8,8))
plt.imshow(im)
plt.show()
Related
Most of the game of life example codes I've seen online have used class and boolean maths (true/false). Instead of this, I have attempted to create one function that iterates over each cell in the matrix and then updates the whole matrix according to the rules of the game, then returns the new matrix. The reason for this is because for my project I will be using pre-prepared input data that are the same size matrixs.
I think this may be currently updating each cell as it goes along and also instead of all cells being only alive (1) or dead (0) it returns values like 118 for example.
An example input data is shown bellow:
[[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]
[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 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 0 0 1 0 1 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 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]]
this is my attempt so far...
i think my issue is with the data type that is in the matrix (numpy int) - in one case i have to add them to find the number of neighbough cells (this determines whether the cell lives of dies after the next tick or generation) and in another i just want to re-write 1 or 0 in the new matix (in same position as input matrix cell in question) based on the neighbough of that cell in the input.
here is my attempt
def tick(matrix):
new_state = np.empty_like(matrix)
for i in range(17):
for j in range(17):
north = matrix[i][j-1]
south = matrix[i][j+1]
west = matrix[i+1][j]
east = matrix[i-1][j]
se = matrix[i+1][i+1]
sw = matrix[i+1][i-1]
ne = matrix[i-1][i+1]
nw = matrix[i-1][i-1]
neibours = np.sum([north, south, west, east, se, sw, ne, nw])
if matrix[i][j] == '0' and neibours == 3:
new_state [i][j] == '1'
if matrix[i][j] == '1' and neibours<2:
new_state [i][j] == '0'
if matrix[i][j] == '1' and neibours>4:
new_state [i][j] == '0'
if matrix[i][j] == '1' and neibours==2 or 3:
new_state [i][j] == '1'
return new_state
world2 = np.loadtxt('data/Loaf.txt',dtype=np.int8)
world3 = np.loadtxt('data/Pentadecathlon.txt',dtype=np.int8)
world1 = np.loadtxt('data/Pulsar.txt',dtype=np.int8)
l = tick(world1)
print(l)
I think i will also need to add some condition that deals with elements on the edge of the matrix that don' have a full set of neighbors. I am really lost as to how I would do this in my function.
This question already has answers here:
Simple adding two arrays using numpy in python?
(2 answers)
Closed 2 years ago.
I'm trying to add multiple arrays together and I'm stuck.
For example, I have those two arrays:
[[1 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 1 0 1]
[0 0 1 0 0 0 0 1 0 0]
[1 0 0 0 1 0 0 0 0 0]
[1 1 0 0 0 0 0 0 2 0]
[0 0 0 0 0 1 0 0 0 0]
[0 0 0 1 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 2]]
and
[[1 0 0 0 0 0 0 0 0 0]
[0 1 0 0 1 0 0 0 0 1]
[0 0 1 0 0 0 0 0 0 0]
[0 1 1 0 0 0 0 0 0 0]
[0 0 0 0 2 0 0 0 0 0]
[0 0 0 0 0 1 0 0 0 0]
[1 0 0 0 0 0 1 0 1 0]
[0 1 0 0 0 1 0 1 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]]
How do I do to add them together such that the resulting array will look like this:
element from the 1st row and from the 1st column (top left) in 1st array + element from the 1st row and from the 1st column (top left) in 2nd array = 2
So the element in the 1st row and 1st column in the resulting array will be 2 and so on for every element.
Thanks
Try the .add method for a numpy array:
sum = np.add(firstarray, secondarray)
This question already has answers here:
Dump a NumPy array into a csv file
(12 answers)
Closed 4 years ago.
I want to save the output of my Python program into a text file to use it in C for some reasons, I don't know how should I do it. The code is:
import networkx as nx
import numpy as np
t_start=0;t_end=1;dt=0.1
tpoints=np.arange(t_start,t_end,dt)
G = nx.grid_2d_graph(20,20, periodic=False, create_using=None)
adj_matrix=nx.adjacency_matrix(G)
print(adj_matrix.todense())
If the number of nodes were less than 20 (like 10 or lower) the output would be:
[[0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0]
[1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0]
[0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0]
[1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0]
[0 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0]
[0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 0]
[0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0]
[0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0]
[0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0]
[0 0 0 0 0 0 1 0 0 1 0 1 0 0 1 0]
[0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1]
[0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0]
[0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0]
[0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1]
[0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0]]
But when the number of nodes increase, the output is like this:
[[0 1 0 ... 0 0 0]
[1 0 1 ... 0 0 0]
[0 1 0 ... 0 0 0]
...
[0 0 0 ... 0 1 0]
[0 0 0 ... 1 0 1]
[0 0 0 ... 0 1 0]]
And so I can't copy it manually to a text file. So I need a command to write this matrix completely to a text file. Thanks for your answers.
The displayed output of a numpy array is not meant to display everything.
If you want to save the array to a file, you can use tofile. There you can define if you want a binary or a text file.
Suppose I have this:
import numpy as np
x = np.zeros((10,16), dtype=np.int)
x[6:8,3:11] = 1
x[4:6,5:7] = 1
x[2:4,4:8] = 1
x[4:6,9:11] = 1
x[7,2] = 1
x[6,11] = 1
x[8,3] = 1
print(x)
Output:
[[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 1 0 0 0 0 0 0 0 0]
[0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0]
[0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0]
[0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0]
[0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0]
[0 0 1 1 1 1 1 1 1 1 1 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]]
And I want to filter it so that elements in a 4 neighborhood (so, up, left, right, bottom) that have less than than 2 neighbors are removed. So, I'd end up with (last three positions set as one removed):
[[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 1 0 0 0 0 0 0 0 0]
[0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0]
[0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0]
[0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0]
[0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0]
[0 0 0 1 1 1 1 1 1 1 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]]
I tried using scipy.ndimage.morphology.binary_closing, scipy.ndimage.morphology.binary_opening, scipy.ndimage.morphology.binary_dilation and scipy.ndimage.morphology.binary_erosion, but the result isn't what I need. I could make 2 for loops and iterate over each element of the array, checking for the neighbor elements, but I feel like there's a better way to do this. Am I mistaken?
I'm more interested in this specific situation (4 neighborhood, keep 2 neighbors), but is it easy to generalize to another neighborhood or number of neighbors (assuming a binary array)?
I managed to get it done like this:
from scipy.signal import convolve2d
kernel = [[0,1,0],[1,1,1],[0,1,0]]
filtered = convolve2d(x, kernel, mode='same')
x[filtered<=2] = 0
Filtered:
[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0]
[0 0 0 1 3 4 4 3 1 0 0 0 0 0 0 0]
[0 0 0 1 3 5 5 3 1 1 1 0 0 0 0 0]
[0 0 0 0 2 4 4 2 1 3 3 1 0 0 0 0]
[0 0 0 1 2 4 4 2 2 4 4 2 0 0 0 0]
[0 0 2 3 4 5 5 4 4 5 5 2 1 0 0 0]
[0 1 2 5 4 4 4 4 4 4 3 2 0 0 0 0]
[0 0 2 2 2 1 1 1 1 1 1 0 0 0 0 0]
[0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]]
And I got the output I wanted. Thank you #user3080953
I have used joblib.dump to store a machine learning model (21 classes).
When I call the model and test it with a hold-out set I get a value which I do not know what metric it is (accuracy, precision, recall, etc)?!!
0.952380952381
So I computed the confusion matrix and the FP, FN, TN, TP.
I used the information from this Link
I also found some code from a Github.
I compared both results (1 and 2). Both give the same value for Accuracy=0.995464852608. But this result is different from the above one!!!
Any ideas? Did I computed correctly TP, FP, TN, FN?
MY CONFUSION MATRIX
[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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 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 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 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 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 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 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 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 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 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 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 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 1 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]]
MY CODE
#Testing with the holdout set
print(loaded_model.score(x_oos, y_oos))
0.952380952381 <------IS IT ACCURACY?
#Calculating the Confusion matrix
cm = confusion_matrix(y_oos, y_oos_pred)
cm_normalized = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
#Calculating values according to link 2.
FP = cm.sum(axis=0) - np.diag(cm)
FN = cm.sum(axis=1) - np.diag(cm)
TP = np.diag(cm)
TN = (21 - (FP + FN + TP)) #I put 21 because I have 21 classes
# Overall accuracy
ACC = np.mean((TP+TN)/(TP+FP+FN+TN))
print(ACC)
0.995464852608 <----IT IS DIFFERENT FROM THE ABOVE ONE.
Your example is a little bit confusing. If you provide some numbers it would be easier to understand and answer. For example just printing cm would be very helpful.
That being said. The way to deconstruct a sklearn.metrics.confusion_matris is as follows (for a binary classification):
true_neg, false_pos, false_neg, false_pos = confusion_matrix(y_oos, y_oos_pred).ravel()
For multiple classes I think the result is closer to what you have, but with the values summed. Like so:
trues = np.diag(cm).sum()
falses = (cm.sum(0) - np.diag(cm)).sum()
Then you can just compute the accuracy with:
ACC = trues / (trues + falses)
** Update**
From your edited question I can now see that in your confusion matrix you have 21 total samples of which 20 where correctly classified. In that case your accuracy is:
$\frac{20}{21} = 0.95238$
This is the value printed by the model_score method. So you are measuring accuracy. You just aren't reproducing it correctly.
n.b sorry for the latex, but hopefully one day StackOverflow will implement it.
Both are Accuracy.
The first one is the overall accuracy: All_True_Positives/All_classes (20/21).
The second one is the average of accuracies from each class. So we add all these values and divide by 21.
[0.9524 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0.9524 1 1 1]