2

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!

Community
  • 1
  • 1
user62622
  • 21
  • 5
  • 1
    You can try something like http://stackoverflow.com/questions/8722735/i-want-to-use-matplotlib-to-make-a-3d-plot-given-a-z-function. Here they are creating the combinations of x and y by careful creation of xs and ys. – Leo Nov 18 '16 at 20:50
  • One way would be to create a `np.linspace` of length `len(x)*len(y)` and then stack two column vectors into a matrix by taking `%` (modulus) and `/` (division) of this array with the lengths – martianwars Nov 18 '16 at 21:02
  • One way would to be to use itertools.combinations over two lists of indexes. Then use the indexes to fetch items from your arrays and pass those to your function – kezzos Nov 18 '16 at 21:05
  • Thank you to all your responses. I will have a try with these and see what I come up with! – user62622 Nov 18 '16 at 21:10

2 Answers2

1

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)]
martianwars
  • 6,380
  • 5
  • 35
  • 44
1

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.

wwii
  • 23,232
  • 7
  • 37
  • 77