How to make a NOR between 2 vectors in python - python

I have two vectors :
predictions = [0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1]
labels = [0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0]
and I need as an output (using python) the true negatives - NOR of these two vectors.
output = [1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0]
I tried with this command but it throw an error :
print not(predictions & labels)
>>>TypeError: unsupported operand type(s) for &: 'list' and 'list'
What is the correct syntax / command to do such a simple thing ?

Native python does not support vector operation. You have to nand individual element
>>> [int(not (p & l)) for p, l in zip(predictions, labels)]
[1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1]
Off -course if you are using numpy, you can achieve what you are envisaging
>>> np.logical_not(np.logical_and(predictions, labels)).astype(int)
array([1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1])
It is worth noting that your output is not Nand but actually Nor, so you have to apply the operations accordingly
>>> np.logical_not(np.logical_or(predictions, labels)).astype(int)
array([1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0])

Here You have to iterate to every item in the list
c=[int(not i&j) for i,j in zip(predictions,labels)]
The operator & is not defined for operands of type list.
The operator not will return True if len(list>0), if the list is empty it will return false.
Also you need to cast booleans to ints to achieve the required result.

With itertools.imap and the operator module:
from operator import eq,and_,or_,xor
from itertools import imap
predictions = [0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1]
labels = [0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0]
#Logical AND
print [int(e) for e in imap(and_,predictions,labels)]
#Logical NAND
print [int(not e) for e in imap(and_,predictions,labels)]
#Logical OR
print [int(e) for e in imap(or_,predictions,labels)]
#Logical NOR
print [int(not e) for e in imap(or_,predictions,labels)]
#Logical XOR
print [int(e) for e in imap(xor,predictions,labels)]
#Logical not XOR
print [int(not e) for e in imap(xor,predictions,labels)]

Related

Conversion between binary vector and 128 bit number

Is there a way to convert back and forth between a binary vector and a 128-bit number? I have the following binary vector:
import numpy as np
bits = np.array([1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0,
1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1,
0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1,
1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1], dtype=np.uint8)
which is a MD5 hash that I am trying use as a feature for a scikit-learn machine learning classifier (I need to represent the hash as a single feature).
As commented above, numpy only goes up to 64bits, but python has variable length ints, so we can do 128bits int no problem.
The following will go from binary in np.array to python int back to binary in np.array.
import numpy as np
bits = np.array(
[
1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0,
1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1,
0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1,
1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1
],
dtype=np.uint8
)
s = "".join(bits.astype("str")) # move from array to string
n = int(s, 2) # convert to int from string of base 2
print(n)
s = bin(n)[2:] # get binary of int, cut "0b" prefix
np.array(list(s), dtype=np.uint8) # put back in np.array

Performing bitwise operations on binary strings made from arrays

Basically I'm trying to grab 1's and 0's values from an array and perform bitwise operations on that.
board = np.array([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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
for x in board:
s += str(x)
s = int(s)
This is obviously not correct however. This has its own binary value and if I perform bitwise operations on it (eg. >>) I'm shifting the underlying binary.
So how can I dynamically create binary strings to perform bitwise operations on?
Any help appreciated.
board = np.array([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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
for x in board:
s += str(x)
s = int(s)
int automatically converts to base 10 but you could also use int(s,2) to convert it to base 2. You'd then get the base 10 representation of your base2 number. So int("110",2) would be 6 and 6<<2 would be 24 or 6>>2 would be 1.
Also in terms of making the stringyfication easier yon can use
s = "".join(map(str, board))

How to count 0's & 1's in a matrix using python?

I have a matrix as shown below ,
matrix([[0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1,
1, 0, 1, 1, 0, 1, 0, 0, 1],
[0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0,
1, 1, 0, 0, 0, 1, 0, 0, 1],
[0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0,
1, 1, 0, 0, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
0, 1, 0, 0, 0, 1, 1, 0, 0],
[1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0,
1, 0, 0, 0, 0, 1, 1, 0, 1],
[0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0,
0, 1, 0, 1, 0, 1, 0, 0, 0],
[0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1,
0, 1, 1, 1, 1, 0, 0, 1, 0],
[0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
1, 0, 1, 0, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0,
1, 0, 0, 1, 0, 0, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 1, 0, 1, 0]])
I want to count the 0's and 1's in that matrix.
The code i tried is ,
def countZeroes(mat):
# start from bottom-left
# corner of the matrix
N = 10;
row = N-1;
col = 0;
# stores number of
# zeroes in the matrix
count = 0;
while (col < N):
# move up until
# you find a 0
while (mat[row][col]):
# if zero is not found
# in current column, we
# are done
if (row < 0):
return count;
row = row - 1;
# add 0s present in
# current column to result
count = count + (row + 1);
# move right to
# next column
col = col + 1;
return count;
The above code is to count 0's.
Could you help me in solving this problem?
I would request you to provide me an answer using loops.
Thanks!
Looks like we don't care at all about the positions of the various 0s and 1s - so, we're not counting on a per-row or per-column basis, then.
matrix = [[0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1,
1, 0, 1, 1, 0, 1, 0, 0, 1],
[0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0,
1, 1, 0, 0, 0, 1, 0, 0, 1],
[0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0,
1, 1, 0, 0, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
0, 1, 0, 0, 0, 1, 1, 0, 0],
[1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0,
1, 0, 0, 0, 0, 1, 1, 0, 1],
[0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0,
0, 1, 0, 1, 0, 1, 0, 0, 0],
[0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1,
0, 1, 1, 1, 1, 0, 0, 1, 0],
[0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
1, 0, 1, 0, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0,
1, 0, 0, 1, 0, 0, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 1, 0, 1, 0]]
The pythonic solution would be to use a comprehension inside a call to the built-in sum() to just count the number of 1s, then subtract that from the size of the matrix:
matrix_height = len(matrix)
matrix_width = len(matrix[0])
num_ones = sum(cell for row in matrix for cell in row)
num_zeroes = (matrix_height * matrix_width) - num_ones
# num_zeroes = 155
However, we can also just use two nested for loops to count the number of zeroes that way:
num_zeroes = 0
for row in matrix:
for cell in row:
if cell == 0:
num_zeroes += 1
# num_zeroes = 155
You can see that the comprehension I demonstrated before is essentially just these two for loops, but in a single line.
You can use sum() and map() to obtain the number of ones. Then subtract that number from the total number of elements to obtain the number of zeroes:
ones = sum(map(sum,matrix))
zeros = sum(map(len,matrix))-ones

removing the first 0 bit value

i want to get the binary value from a string, but why if i print the binary value and save it into an array there is always 0 bit get inserted automatically, i know that its from the bitwise operation inside the loop, how can i delete it and get the actual binary value from a string?
this is the code
def padding():
a = "Testing"
byte_a = a.encode('utf-8')
print(byte_a)
print(bin(byte_a[0]))
print(bin(byte_a[1]))
print(bin(byte_a[2]))
i = 0
x = []
#byte_a.append(1)
while True:
x.insert(i, ((byte_a[i//8]>>(7-(i%8)))&1))
print(x)
i+=1
and here is the output:
b'Testing'
0b1010100
0b1100101
0b1110011
[0]
[0, 1]
[0, 1, 0]
[0, 1, 0, 1]
[0, 1, 0, 1, 0]
[0, 1, 0, 1, 0, 1]
[0, 1, 0, 1, 0, 1, 0]
[0, 1, 0, 1, 0, 1, 0, 0]
[0, 1, 0, 1, 0, 1, 0, 0, 0]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0]
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1]
...
as you can see the array had the first value of 0 for every binary.
thanks guys

Search through a 2-dimensional list without numpy

I'm looking to define a function that accepts two parameters: an int and a list.
If the function finds the integer in the list it returns its coordinates.
For example how would I do that for the number 4 in the following list, without using numpy?
l = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 2, 1, 1, 0, 1, 1, 1, 0],
[0, 1, 0, 1, 0, 0, 0, 1, 0],
[0, 1, 0, 1, 1, 1, 0, 1, 0],
[0, 1, 0, 0, 0, 1, 0, 1, 0],
[0, 1, 1, 1, 0, 1, 0, 1, 0],
[0, 0, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 1, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 0, 0, 0, 0, 1, 0],
[0, 1, 0, 1, 1, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 1, 1, 0, 1, 1, 4, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
]
You can assume that the target will always show up only once and will always be contained in the list.
The target will always show up only once and will always be contained in the list
You can use enumerate to enumerate the outer lists and the elements of the inner lists.
def coords(lst, find):
return next((i, j) for i, sub in enumerate(lst)
for j, x in enumerate(sub)
if x == find)
Demo with your list l:
>>> coords(l, 2)
>>> (1, 1)
>>> coords(l, 1)
>>> (1, 2)
In case you later want to adapt the function to work properly if the target is not in the list, remember that next takes an optional default argument.
You can do something like this:
l = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 2, 1, 1, 0, 1, 1, 1, 0],
[0, 1, 0, 1, 0, 0, 0, 1, 0],
[0, 1, 0, 1, 1, 1, 0, 1, 0],
[0, 1, 0, 0, 0, 1, 0, 1, 0],
[0, 1, 1, 1, 0, 1, 0, 1, 0],
[0, 0, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 1, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 0, 0, 0, 0, 1, 0],
[0, 1, 0, 1, 1, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 1, 1, 0, 1, 1, 4, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
]
def findElement(element, l):
for i in range(len(l)):
for j in range(len(l[i])):
if element==l[i][j]:
return (i,j)
return None
print(findElement(4,l))
Output:
(11, 7)
I would used solution like this:
#!/usr/bin/env ipython
# ---------------------
l = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 2, 1, 1, 0, 1, 1, 1, 0],
[0, 1, 0, 1, 0, 0, 0, 1, 0],
[0, 1, 0, 1, 1, 1, 0, 1, 0],
[0, 1, 0, 0, 0, 1, 0, 1, 0],
[0, 1, 1, 1, 0, 1, 0, 1, 0],
[0, 0, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 1, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 0, 0, 0, 0, 1, 0],
[0, 1, 0, 1, 1, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 1, 1, 0, 1, 1, 4, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
]
# ----------------------------------
def search(value,listin):
coords = [[ival,kkval] for ival,dd in enumerate(listin) for kkval,val in enumerate(dd) if val==value]
return coords
# ----------------------------------
result = search(4,l)
print result
where I defined a function search, which can be used to search for certain value from an input list.
Here is my approach:
def matrix_search(target, matrix):
for row_index, row in enumerate(matrix):
try:
return (row_index, row.index(target))
except ValueError:
pass
raise ValueError('Target {} not found'.format(target))
Sample usage:
print(matrix_search(4, l))
Notes
To search a simple list, use the .index() method
The .index() method will either return the index of the element if found or throw a ValueError if not found. In our context, we just ignore this exception and move on to the next row.
At the end of the loop, we will throw an exception because the element is not found

Categories