Why do I have to use a.any() or a.all() in this code? - numpy

In this code below, I found that when I put a number it works, but when I put ndarray then it would post an error message.
Why do I have to use a.any() or a.all() in this case?
import numpy as np
def ht(x):
if x%2 == 1:
return 1
else:
return 0
ht(1)
[Example]
step(1): 1
step(np.array([1,2,3,4])) : The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

when evaluating if statements, you have to pass in a bool.
if var:
pass
var has to be of type bool.
if x is a number, then x%2 == 1 is a bool.
if x is a np.array, then x%2 == 1 is a np.array which isn't a bool, but rather an array of bool, in which each cell states whether *that cell* %2 == 1.
You can check if all elements in it are truthy (1) or if any of them are truthy with np.all or np.any.

This is because when np.array([1,2,3,4])%2 is performed, the output is also in np array format - array([1, 0, 1, 0]). To check whether these individual array elements are 1 or 0, one has to use the any() or all() function. There is no problem when we pass a single element.
So, here is the modified code -
import numpy as np
def ht(x):
if all(x%2 == 1): #denotes true when all modulus results are == 1
return 1
else:
return 0
ht(np.array([1,2,3,4]))
Output for the above code is 0
import numpy as np
def ht(x):
if any(x%2 == 1): #denotes true when any modulus result is == 1
return 1
else:
return 0
ht(np.array([1,2,3,4]))
Output for the above code is 1

Related

How to create a custom conditional activation function

I want to create custom activation function in TF2. The math is like this:
def sqrt_activation(x):
if x >= 0:
return tf.math.sqrt(x)
else:
return -tf.math.sqrt(-x)
The problem is that I can't compare x with 0 since x is a tensor. How to achieve this functionality?
You can skip the comparison by doing,
def sqrt_activation(x):
return tf.math.sign(x)*tf.math.sqrt(tf.abs(x))
YOu need to use tf backend functions and convert your code as follows:
import tensorflow as tf
#tf.function
def sqrt_activation(x):
zeros = tf.zeros_like(x)
pos = tf.where(x >= 0, tf.math.sqrt(x), zeros)
neg = tf.where(x < 0, -tf.math.sqrt(-x), zeros)
return pos + neg
note that this function check all tensor to meet on those conditions ergo returning the pos + neg line

Explanation of pandas DataFrame.assign() behaviour using lambda

import pandas as pd
import numpy as np
np.random.seed(99)
rows = 10
df = pd.DataFrame ({'A' : np.random.choice(range(0, 2), rows, replace = True),
'B' : np.random.choice(range(0, 2), rows, replace = True)})
def get_C1(row):
return row.A + row.B
def get_C2(row):
return 'X' if row.A + row.B == 0 else 'Y'
def get_C3(row):
is_zero = row.A + row.B
return "X" if is_zero else "Y"
df = df.assign(C = lambda row: get_C3(row))
Why the get_C2 and get_C3 functions return an error?
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
You're thinking that df.assign, when passed a function, behaves like df.apply with axis=1, which calls the function for each row.
That's incorrect.
Per the docs for df.assign
Where the value is a callable, evaluated on df
That means that the function you pass to assign is called on the whole dataframe instead of each individual row.
So, in your function get_C3, the row parameter is not a row at all. It's a whole dataframe (and should be renamed to df or something else) and so row.A and row.B are two whole columns, rather than single cell values.
Thus, is_zero is a whole column as well, and ... if is_zero ... will not work.

iterating pandas rows using .apply()

I wanted to iterate through the pandas data frame but for some reason it does not work with .apply() method.
train = pd.read_csv('../kaggletrain')
pclass = train['Pclass']
# pclass has list of data with either 1, 2 or 3..
# so wanted to return if the cell is 1 then return True or everything False
def abc(pclass):
if pclass == 1:
return True
else:
return False
ABCDEFG = train.apply(abc, axis=1)
This gives valueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Thank you for your help
ABCDEFG = train[train['pclass']==1]

Reshape a variable numpy array

Suppose i have a numpy array u with a given shape, a a divisor d of the total number of entries in u. How can i fastly reshape u to be shaped (something,d) ?
The case where u is just a double should be included as well -> (1,1)
The case where u is empty should become a (0,d) shaped array
You want to use reshape
u.reshape(-1, d)
There is no double in Python you do you mean float ?
In short :
import numpy as np
def div_reshape(arr, div):
if arr.size == 0:
return np.empty(shape=(0, div))
elif arr.size == 1:
return arr.reshape(1, 1)
else:
return arr.reshape(-1, d)

Numpy creation fromfunction

I need something like this
def qqq(i,j):
if i+j>2:
return 0.5
else:
return 0
n=3
dcdt=np.fromfunction(lambda i,j: qqq(i,j)*i*j, (n,n), dtype=int)
but with more complicated qqq. But it leads to the error "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()". I know the problem is that function is called once. How can I do such array creation with the "if-elif-else" structure in the function?
You should turn your qqq function into something like:
def qqq(i, j):
return np.where(i + j > 2, 0.5, 0)
See np.where's docs for details.