Q: Feeding all combinations of x and y array into function f(x,y) New to python and trying to teach myself the language. I understand the basics from R and SAS however I am still learning how to manipulate arrays and learn basic python in spyder. 
I would really love your help with feed both x and y into a function f(x,y) (e.g sin(xy) for simplicity). 
Typically in R, I would create a data frame by expanding values of x and y to create every combination (unique x and y per row) then run my these rows through my function and attach a new column in my dataframe, and plot the contour plot using lattice etc. 
For the same function f(x,y) = z = sin(x,y), in python I have tried
x = np.linspace(0, 1, 100)
y = np.linspace(-1, 11, 100)
z= np.equ(x,y)

which obviously wouldnt work but I am unsure really how to do it.
This was attempted after trying to manipulate the following code from: Matplotlib line plot of x values against y:
import numpy as np
import matplotlib.pyplot as plt

fig,ax = plt.subplots(1)

# create some x data and some integers for the y axis
x = np.array([3,5,2,4])
y = np.arange(4)

# plot the data
ax.plot(x,y)

# tell matplotlib which yticks to plot 
ax.set_yticks([0,1,2,3])

# labelling the yticks according to your list
ax.set_yticklabels(['A','B','C','D'])

Thank you for any help! 

A: You need to use itertools.product in this case. It can be used to generate a list having all possible combinations.
For example, if A = [1, 2] and B = [3, 4]
itertools.product would return an iterable which can be stored in an array like this,
C = list(itertools.product(A, B))
# C = [(1,3), (1,4), (2,3), (2,4)]


A: If you are using a ufunc that takes two arguments, use numpy.meshgrid() like this:
x, y = np.meshgrid(np.linspace(0, 1, 5), np.linspace(-1, 11, 5))
r = np.equal(x, y)

If you are using your own function that takes one argument of two items - (x,y) or [x,y] ...:
def f(one_d_array):
    return one_d_array[0] == one_d_array[1]

Concatenate the x's and y's from meshgrid
q = np.concatenate((x[...,None],y[...,None]), 2)

Then use numpy.apply_along_axis
np.apply_along_axis(f, 2, q)

If you are using your own function that takes an x and y argument, use the arrays obtained from meshgrid.
def f1(x, y):
    '''Returns 4x^2 + 2y^2'''
    return 4*np.square(x) + 2*np.square(y)

f1(x, y)


If your arrays are large, try to avoid using apply_along_axis by restructuring your function to work on entire arrays instead of slices.
