numpy packbits pack to uint16 array - python-3.x

I´ve got a 3D numpy bit array, I need to pack them along the third axis. So exactly what numpy.packbits does. But unfortunately it packs it only to uint8, but I need more data, is there a similar way to pack it to uint16 or uint32?

Depending on your machine's endianness it is either a matter of simple view casting or of byte swapping and then view casting:
>>> a = np.random.randint(0, 2, (4, 16))
>>> a
array([[1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1],
[0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1]])
>>> np.packbits(a.reshape(-1, 2, 8)[:, ::-1]).view(np.uint16)
array([53226, 23751, 25853, 64619], dtype=uint16)
# check:
>>> [bin(x + (1<<16))[-16:] for x in _]
['1100111111101010', '0101110011000111', '0110010011111101', '1111110001101011']
You may have to reshape in the end.

Related

Hermitian Adjacency Matrix of Digraph

I am trying to find a pythonic way to calculate the Hermitian adjacency matrix in Python and I'm really struggling. The definition of a Hermitian Adjacency matrix is shown in this image:
It works as follows. Lets say we have two nodes named i and j. If there is an directed edge going from both i to j and j to i, then the corresponding matrix value at location [ i, j ] should be set to 1. If there is only a directed edge from i to j, then the matrix element at location [i, j] should be set to +i. And if there is only a directed edge from j to i then the matrix element at location [i, j] should be set to -i. All other matrix values are set to 0.
I cannot figure out a smart way to make this Hermitian Adjacency Matrix that doesn't involve iterating through my nodes one by one. Any advice?
I don't think there's a built-in for this, so I've cobbled together my own vectorised solution:
import numpy as np
import networkx as nx
# Create standard adjacency matrix
A = nx.linalg.graphmatrix.adjacency_matrix(G).toarray()
# Add to its transpose and convert from sparse array
B = A + A.T
# Get row index matrix
I = np.indices(B.shape)[0] + 1
# Apply vectorised formula to get Hermitian adjacency matrix
H = np.multiply(B/2 * (2*I)**(B%2), 2*A-1).astype(int)
Explanation
Let's start with a directed graph:
We start by creating the normal adjacency matrix using nx.linalg.graphmatrix.adjacency_matrix(), giving us the following matrix:
>>> A = nx.linalg.graphmatrix.adjacency_matrix(G).toarray()
[[1, 1, 0, 1, 0, 1, 0, 0],
[1, 0, 0, 1, 0, 0, 1, 0],
[1, 1, 1, 1, 0, 1, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 1, 0, 0, 0, 0],
[1, 1, 0, 0, 1, 0, 1, 1],
[0, 1, 0, 0, 1, 0, 0, 1],
[0, 0, 0, 0, 1, 0, 0, 0]]
We can then add this matrix to its transpose, giving us 2 in every location where there is a directed edge going from i to j and vice-versa, a 1 in every location where only one of these edges exists, and a 0 in every location where no edge exists:
>>> B = A + A.T
>>> B
[[2, 2, 1, 1, 1, 2, 0, 0],
[2, 0, 1, 2, 0, 1, 2, 0],
[1, 1, 2, 1, 0, 1, 0, 0],
[1, 2, 1, 0, 1, 0, 0, 0],
[1, 0, 0, 1, 0, 1, 1, 1],
[2, 1, 1, 0, 1, 0, 1, 1],
[0, 2, 0, 0, 1, 1, 0, 1],
[0, 0, 0, 0, 1, 1, 1, 0]]
Now, we want to apply a function to the matrix so that 0 maps to 0, 2 maps to 1, and 1 maps to the row number i. We can use np.indices() to get the row number, and the following equation: x/2 * (2*i)**(x%2), where i is the row number and x is the element. Finally, we need to multiply elements in positions where no edge ij exists by -1. This can be vectorised as follows:
>>> I = np.indices(B.shape)[0] + 1
>>> H = np.multiply(B/2 * (2*I)**(B%2), 2*A-1).astype(int)
>>> H
[[ 1, 1, -1, 1, -1, 1, 0, 0],
[ 1, 0, -2, 1, 0, -2, 1, 0],
[ 3, 3, 1, 3, 0, 3, 0, 0],
[-4, 1, -4, 0, -4, 0, 0, 0],
[ 5, 0, 0, 5, 0, -5, -5, -5],
[ 1, 6, -6, 0, 6, 0, 6, 6],
[ 0, 1, 0, 0, 7, -7, 0, 7],
[ 0, 0, 0, 0, 8, -8, -8, 0]]
As required.
We can check that this is correct by using a naïve iterate-through-nodes approach:
>>> check = np.zeros([8,8])
>>> for i in G.nodes:
for j in G.nodes:
if (i, j) in G.edges:
if (j, i) in G.edges:
check[i-1, j-1] = 1
else:
check[i-1, j-1] = i
else:
if (j, i) in G.edges:
check[i-1, j-1] = -i
else:
check[i-1, j-1] = 0
>>> (check == H).all()
True

Convert list of lists of 1 and 0 in black and white image in Python

I would like to know if there is a simple way to convert a simple list of 0 and 1 for example:
[[1, 1, 0, 0, 0, 0, 1, 1],
[1, 0, 1, 1, 1, 1, 0, 1],
[0, 1, 0, 1, 1, 0, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 0, 1, 1, 0, 1, 0],
[0, 1, 1, 0, 0, 1, 1, 0],
[1, 0, 1, 1, 1, 1, 0, 1],
[1, 1, 0, 0, 0, 0, 1, 1]]
Into a black and white image, for example for the previous list, this image :
smiley
Thanks for your help!
You can simply use matplolib (I named as X your input matrix):
import matplotlib.pyplot as plt
im = plt.imshow(X, cmap='Greys')
plt.show()

Python: Converting Binary to Decimal

What I'm currently doing is a implementation of Genetic Algorithms. I have written my Crossover and mutation methods and now i'm currently writing my Fitness method.
I need to convert my list of 0s and 1s to decimal values for calculating distance.
My current output that I'm working with are a list of integer values of 1s and 0s. (Example below):
[[0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1], [0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1]]
<class 'list'>
I want to convert these numbers to their respected binary equivalent.
I have tried converting the list to groups of 4 and then calling a binaryToDecimal function to convert the bits to decimal values. However, Im getting an error 'TypeError: 'numpy.ndarray' object is not callable'.
I have summarized my code and this is what it looks like so far.
def converting_binary_to_decimal(L):
output = []
for l in L:
l = list(map(str, l))
sub_output = []
for j in range(0, len(l)-1, 4):
sub_output.append(int(''.join(l[j:j+4]), 2))
output.append(sub_output)
return output
def chunks(L, n):
for i in range(0, len(L), n):
yield L[i:i+n]
def fitness(child):
newList1=list(chunks(child[0], 4))
newList2=list(chunks(child[1], 4))
if __name__ == "__main__":
myFitness = fitness(afterMU)
A sample output of what i want is:
[[0, 13, 6, 8, 12, 8, 10, 9, 15], [0, 8, 7, 0, 4, 4, 1, 8, 15]]
Try this code.
def converting_binary_to_decimal(L):
output = []
for l in L:
l = list(map(str, l))
sub_output = []
for j in range(0, len(l)-1, 4):
sub_output.append(int(''.join(l[j:j+4]), 2))
output.append(sub_output)
return output
L = [[0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1], [0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1]]
converting_binary_to_decimal(L)
I think i figured it out.
x=[0, 1, 1, 0]
k = 4
n = len(x)//k
for i in range(n):
y = x[i*k:(i+1)*k]
y = [str(j) for j in y]
y = ''.join(y)
y = int(y,2)
print(y)
Thank you.

How to find contiguous regions in 2D Data

I'd like to label non-contiguous regions in an image with different labels.
I guess this should be possible with scikit-learn.
The image is stored for example in a 2D numpy.ndarray with zeroes and ones, the ones beeing different contiguous regions.
Let's have a look at the following very simple array where we have two contiguous regions of ones but these to regions are separated from each other by zeroes.
np.array([
[1, 1, 1, 0, 0, 0],
[1, 1, 0, 0, 0, 1],
[0, 1, 0, 1, 0, 1],
[1, 1, 0, 1, 1, 1]
], dtype = int)
the algorithm should label the top-left contiguous region with a label like '1' and the right bottom contiguous region with a second label '2'.
np.array([
[1, 1, 1, 0, 0, 0],
[1, 1, 0, 0, 0, 2],
[0, 1, 0, 2, 0, 2],
[1, 1, 0, 2, 2, 2]
], dtype = int)
Any hints how to do this?
import numpy as np
from skimage.measure import label
a = np.array([[1, 1, 1, 0, 0, 0],
[1, 1, 0, 0, 0, 1],
[0, 1, 0, 1, 0, 1],
[1, 1, 0, 1, 1, 1]], dtype = int)
label(a)

Conversion of numpy 2d array to ENVI binary file through gdal

I have SAR CEOS format files which consist of data file, leader file, null volume directory file and volume directory file.
I am reading the data file using gdal ReadAsArray and then I am doing operations on this 2d Array and now I want to save this 2d array as an ENVI binary file.
Kindly guide how to do this in Python 3.5.
Find help for Tutorial Website: https://pcjericks.github.io/py-gdalogr-cookbook/
Such as the example of
import gdal, ogr, os, osr
import numpy as np
def array2raster(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array):
cols = array.shape[1]
rows = array.shape[0]
originX = rasterOrigin[0]
originY = rasterOrigin[1]
driver = gdal.GetDriverByName('ENVI')
outRaster = driver.Create(newRasterfn, cols, rows, 1, gdal.GDT_Byte)
outRaster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight))
outband = outRaster.GetRasterBand(1)
outband.WriteArray(array)
outRasterSRS = osr.SpatialReference()
outRasterSRS.ImportFromEPSG(4326)
outRaster.SetProjection(outRasterSRS.ExportToWkt())
outband.FlushCache()
def main(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array):
reversed_arr = array[::-1] # reverse array so the tif looks like the array
array2raster(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,reversed_arr) # convert array to raster
if __name__ == "__main__":
rasterOrigin = (-123.25745,45.43013)
pixelWidth = 10
pixelHeight = 10
newRasterfn = 'test.tif'
array = np.array([[ 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, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1],
[ 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
[ 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1],
[ 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
[ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 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]])
main(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array)

Resources