I have a function call to cobyla, that does not terminate.
I want to find a local minimum of some (multivariate) polynomial, in a given orthant.
The smallest example, I could reproduce is the following.
import numpy as np
import scipy.optimize
A = np.array([[ 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 6, 12, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 1, 2],
[ 0, 0, 2, 2, 2, 4, 10, 0, 4, 4, 12, 4, 0, 2, 4, 0, 3, 4, 3, 3, 2, 3, 3, 4, 3, 2, 3, 3, 4, 3],
[ 0, 4, 0, 6, 10, 10, 4, 4, 4, 8, 2, 0, 4, 2, 4, 2, 4, 4, 3, 4, 3, 5, 3, 4, 4, 4, 3, 4, 4, 4],
[ 0, 0, 6, 0, 0, 6, 2, 12, 10, 0, 2, 8, 0, 8, 4, 2, 5, 3, 5, 3, 3, 4, 4, 4, 2, 3, 4, 4, 3, 4]])
b = np.array([ 3.81330727e+00, 1.30927853e+00, 1.89829563e+00, 1.55301205e+00, 2.05509780e+00, 4.72913144e+00, 8.64125139e+00, 6.78452109e+00, 1.97505381e+01, 8.10184002e+00, 8.56817472e+00, 1.76581791e+00, 6.90448362e+00, 8.44460914e-02, 1.52023325e+00, -1.97710183e+00, -1.66933212e-01, -2.71655065e-01, -2.03262146e+00, -6.74143747e-01, -1.53382538e+00, -9.94362458e-01, 1.86147837e-01, -6.23838626e-01, 1.04835921e+00, 3.49272629e-01, -6.47927068e-01, -4.69780766e-01, 1.48099164e-02, 3.61251102e-01])
x0 = np.array([ 3.75422451, -4.13253284, -46.27451838, -29.48396097])
def f(x):
return np.dot(np.prod(np.power(x,A.T),axis = 1),b)
res = scipy.optimize.fmin_cobyla(f, x0, lambda x: x*np.array([1,-1,-1,-1]), disp = 3)
Then the last line of code does not terminate.
Even with maximum display level, I do not get a single line of output.
Worse, Ctrl+C does not terminate the computation in IPython (I assume, the code is stuck in Fortran).
How can I avoid this problem?
I believe there is an issue in the way you have described constraints.
I have tried the following 2 forms of code and it works:
import numpy as np
import scipy.optimize
A = np.array([[ 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 6, 12, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 1, 2],
[ 0, 0, 2, 2, 2, 4, 10, 0, 4, 4, 12, 4, 0, 2, 4, 0, 3, 4, 3, 3, 2, 3, 3, 4, 3, 2, 3, 3, 4, 3],
[ 0, 4, 0, 6, 10, 10, 4, 4, 4, 8, 2, 0, 4, 2, 4, 2, 4, 4, 3, 4, 3, 5, 3, 4, 4, 4, 3, 4, 4, 4],
[ 0, 0, 6, 0, 0, 6, 2, 12, 10, 0, 2, 8, 0, 8, 4, 2, 5, 3, 5, 3, 3, 4, 4, 4, 2, 3, 4, 4, 3, 4]])
b = np.array([ 3.81330727e+00, 1.30927853e+00, 1.89829563e+00, 1.55301205e+00, 2.05509780e+00, 4.72913144e+00, 8.64125139e+00, \
6.78452109e+00, 1.97505381e+01, 8.10184002e+00, 8.56817472e+00, 1.76581791e+00, 6.90448362e+00, 8.44460914e-02, 1.52023325e+00, \
-1.97710183e+00, -1.66933212e-01, -2.71655065e-01, -2.03262146e+00, -6.74143747e-01, -1.53382538e+00, -9.94362458e-01, 1.86147837e-01, \
-6.23838626e-01, 1.04835921e+00, 3.49272629e-01, -6.47927068e-01, -4.69780766e-01, 1.48099164e-02, 3.61251102e-01])
x0 = np.array([ 3.75422451, -4.13253284, -46.27451838, -29.48396097])
def fun(x):
return np.dot(np.prod(np.power(x,A.T),axis = 1),b)
def constraint_func(x_in):
factor = np.array([1,-1,-1,-1])
constraints_list = []
for i in range(len(x_in)):
constraints_list.append({lambda x: x[i]*factor[i]})
res = scipy.optimize.fmin_cobyla(fun, x0, constraint_func, disp = 3)
Another way using another function of Scipy library:
import numpy as np
import scipy.optimize
A = np.array([[ 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 6, 12, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 1, 2],
[ 0, 0, 2, 2, 2, 4, 10, 0, 4, 4, 12, 4, 0, 2, 4, 0, 3, 4, 3, 3, 2, 3, 3, 4, 3, 2, 3, 3, 4, 3],
[ 0, 4, 0, 6, 10, 10, 4, 4, 4, 8, 2, 0, 4, 2, 4, 2, 4, 4, 3, 4, 3, 5, 3, 4, 4, 4, 3, 4, 4, 4],
[ 0, 0, 6, 0, 0, 6, 2, 12, 10, 0, 2, 8, 0, 8, 4, 2, 5, 3, 5, 3, 3, 4, 4, 4, 2, 3, 4, 4, 3, 4]])
b = np.array([ 3.81330727e+00, 1.30927853e+00, 1.89829563e+00, 1.55301205e+00, 2.05509780e+00, 4.72913144e+00, 8.64125139e+00, \
6.78452109e+00, 1.97505381e+01, 8.10184002e+00, 8.56817472e+00, 1.76581791e+00, 6.90448362e+00, 8.44460914e-02, 1.52023325e+00, \
-1.97710183e+00, -1.66933212e-01, -2.71655065e-01, -2.03262146e+00, -6.74143747e-01, -1.53382538e+00, -9.94362458e-01, 1.86147837e-01, \
-6.23838626e-01, 1.04835921e+00, 3.49272629e-01, -6.47927068e-01, -4.69780766e-01, 1.48099164e-02, 3.61251102e-01])
x0 = np.array([ 3.75422451, -4.13253284, -46.27451838, -29.48396097])
def fun(x):
return np.dot(np.prod(np.power(x,A.T),axis = 1),b)
def constraint_func(x_in):
factor = np.array([1,-1,-1,-1])
constraints_list = []
for i in range(len(x_in)):
constraints_list.append({'type': 'ineq', 'fun': lambda x: x[i]*factor[i]})
return constraints_list
constraints = constraint_func(x0)
res = scipy.optimize.minimize(fun, x0, method='COBYLA', constraints= constraints)
print(res)
Related
I want to generate random result with weights based on the previous result.
I am generating random results with weights in the following manner
a = [1, 2, 3, 4, 5, 6]
results = random.choices(a, weights=(
(10, 20, 30, 30, 10, 6)), k=100)
print (results[0:100]
What I want to do is if results[n] = 1, the next result cannot be 6(i.e. it can be between 1 and 5).
I am new to this page and python. Any help would be useful
Using Kelly Bundy's suggestion from the comments:
a = [1, 2, 3, 4, 5, 6]
choices = random.choices(a, weights=(10, 20, 30, 30, 10, 6), k=100)
# print(choices)
for i, (prev, curr) in enumerate(zip(choices[:-1], choices[1:])):
if prev == 1 and curr == 6:
# print(f'Rerolled {i + 1}')
choices[i + 1] = random.choices(a, weights=(10, 20, 30, 30, 10, 0), k=1)[0]
print(choices)
Example Output:
[5, 4, 4, 1, 3, 4, 5, 6, 3, 4, 1, 2, 4, 2, 4, 3, 1, 3, 2, 3, 1, 2, 5, 4, 4, 3, 6, 4, 3, 4, 1, 5, 1, 3, 1, 3, 2, 1, 3, 4, 2, 4, 4, 1, 5, 2, 4, 4, 4, 6, 3, 3, 3, 2, 1, 4, 2, 2, 5, 4, 4, 2, 2, 4, 1, 3, 4, 4, 5, 4, 4, 4, 4, 3, 1, 4, 3, 4, 4, 4, 4, 4, 4, 2, 3, 5, 3, 2, 4, 4, 1, 2, 5, 6, 3, 4, 4, 6, 4, 3]
You could change the corresponding weight for 6 to 0 for the next choice if the previous choice was a 1:
a = [1, 2, 3, 4, 5, 6]
choices = []
k = 100
i = 0
previous_choice_1 = False
while i < k:
if previous_choice_1:
choice = random.choices(a, weights=(10, 20, 30, 30, 10, 0), k=1)[0]
else:
choice = random.choices(a, weights=(10, 20, 30, 30, 10, 6), k=1)[0]
choices.append(choice)
previous_choice_1 = choice == 1
i += 1
print(choices)
Example Output:
[6, 3, 3, 6, 2, 3, 3, 1, 2, 3, 6, 1, 2, 2, 6, 4, 3, 3, 2, 2, 1, 2, 3, 4, 4, 3, 2, 5, 4, 4, 3, 3, 4, 3, 3, 3, 1, 4, 5, 1, 2, 4, 4, 2, 4, 3, 4, 3, 6, 4, 1, 5, 3, 4, 4, 2, 4, 3, 4, 3, 3, 4, 3, 2, 2, 2, 3, 4, 3, 2, 1, 4, 4, 3, 3, 1, 3, 4, 5, 4, 4, 3, 1, 2, 2, 6, 3, 2, 3, 3, 4, 2, 1, 2, 4, 3, 3, 3, 1, 4]
I would like to loop through a list of values. If there is a value greater than 3, then select all the following values while the value is greater or equal than 1 (or stop before it drops lower than 1). The rest of the values in the list should be zero until another value down the list is greater than 3 and the process repeats itself.
Example:
If I have the following list:
l = [1, 3, 2, 3, 2, 4, 1, 3, 5, 6, 7, 6, 7, 8, 1, 0, 1, 2, 1, 3, 4, 7, 8, 9, 7, 5, 2, 1, 2, 4, 7, 8, 1, 3]
I would like to get get the following:
o = [0, 0, 0, 0, 0, 4, 1, 0, 5, 6, 7, 6, 7, 8, 1, 0, 0, 0, 0, 0, 4, 7, 8, 9, 7, 5, 2, 1, 0, 4, 7, 8, 1, 0]
So far I managed to get all values greater that 3 and the rest 0, but I don't know how to integrate the other conditon:
l = [1, 3, 2, 3, 2, 4, 1, 3, 5, 6, 7, 6, 7, 8, 1, 0, 1, 2, 1, 3, 4, 7, 8, 9, 7, 5, 2, 1, 2, 4, 7, 8, 1, 3]
o = [0] * len(l)
for index in range(len(l)):
if l[index] > 3:
o[index] = l[index]
else:
o[index] = 0
output:
[0, 0, 0, 0, 0, 4, 0, 0, 5, 6, 7, 6, 7, 8, 0, 0, 0, 0, 0, 0, 4, 7, 8, 9, 7, 5, 0, 0, 0, 4, 7, 8, 0, 0]
I would use a flag to control which values to let through.
Also, I would use a generator:
def a_filter(items, on=3, off=1):
through = False
for item in items:
if item > on:
through = True
elif item < off:
through = False
yield item if through else 0
if item <= off:
through = False
l = [1, 3, 2, 3, 2, 4, 1, 3, 5, 6, 7, 6, 7, 8, 1, 0, 1, 2, 1, 3, 4, 7, 8, 9, 7, 5, 2, 1, 2, 4, 7, 8, 1, 3]
o = [0, 0, 0, 0, 0, 4, 1, 0, 5, 6, 7, 6, 7, 8, 1, 0, 0, 0, 0, 0, 4, 7, 8, 9, 7, 5, 2, 1, 0, 4, 7, 8, 1, 0]
print(l)
# [1, 3, 2, 3, 2, 4, 1, 3, 5, 6, 7, 6, 7, 8, 1, 0, 1, 2, 1, 3, 4, 7, 8, 9, 7, 5, 2, 1, 2, 4, 7, 8, 1, 3]
print(o)
# [0, 0, 0, 0, 0, 4, 1, 0, 5, 6, 7, 6, 7, 8, 1, 0, 0, 0, 0, 0, 4, 7, 8, 9, 7, 5, 2, 1, 0, 4, 7, 8, 1, 0]
print(list(a_filter(l)))
# [0, 0, 0, 0, 0, 4, 1, 0, 5, 6, 7, 6, 7, 8, 1, 0, 0, 0, 0, 0, 4, 7, 8, 9, 7, 5, 2, 1, 0, 4, 7, 8, 1, 0]
print(o == list(a_filter(l)))
# True
I have created a list
a=[1,2,3,4,5]*100
I now need to create another list that will contain the first 8 prime number locations from within a.
I have tried these two lines of code and they didn't work
b=a[2:3:5:7:11:13:17:19]
a[2:3:5:7:11:13:17:19]=b
The output for list A is "[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]" so its the locations 2,3,5,7,11,13,17,19 out of that output
a=[1,2,3,4,5]*100
indices = [2,3,5,7,11,13,17,19]
b = []
for i in indices:
b.append(a[i])
print(b)
You have to access each element individually. b=a[2:3:5:7:11:13:17:19] is not valid syntatically in Python. Actually, this is not the way to access elements at particular indices.
Pythonic way to do the same thing (It will reduce code length) using List Comprehension:
indices = [2,3,5,7,11,13,17,19]
b = [a[i] for i in indices]
I would try it like this using list comprehension (beware the test_prime method is not optimized at all):
def test_prime(n):
if (n==1):
return False
elif (n==2):
return True;
else:
for x in range(2,n):
if(n % x==0):
return False
return True
a=[1,2,3,4,5]*100
b = [item for item in range(len(a)) if test_prime(a[item])]
b = b[0:8]
print b
which outputs (note Python counts from 0, so the first element of an array is 0 and not 1):
[1, 2, 4, 6, 7, 9, 11, 12]
How would I find the values from a certain column in an array? For example I have:
[1, 1, 2, 4, 1, 7, 1, 7, 6, 9]
[1, 2, 5, 3, 9, 1, 1, 1, 9, 1]
[7, 4, 5, 1, 8, 1, 2, 0, 0, 4]
[1, 4, 1, 1, 1, 1, 1, 1, 8, 5]
[9, 0, 0, 0, 0, 0, 1, 1, 9, 8]
[7, 4, 2, 1, 8, 2, 2, 2, 9, 7]
[7, 4, 2, 1, 7, 1, 1, 1, 0, 5]
[3, 4, 5, 3, 4, 5, 9, 1, 0, 9]
[0, 0, 5, 1, 1, 1, 9, 7, 7, 7]
If I wanted to list all of the values of column 5, how would I do this? I have figured out how to do this for the rows, but for the columns it is tricky, since they are all part of a separate list. I have not been able to find anything about this and I am very new to Python so I don't really know what I don't know.
It's simple. Just use l[i][4] to print 5th column value.
l = [
[1, 1, 2, 4, 1, 7, 1, 7, 6, 9],
[1, 2, 5, 3, 9, 1, 1, 1, 9, 1],
[7, 4, 5, 1, 8, 1, 2, 0, 0, 4],
[1, 4, 1, 1, 1, 1, 1, 1, 8, 5],
[9, 0, 0, 0, 0, 0, 1, 1, 9, 8],
[7, 4, 2, 1, 8, 2, 2, 2, 9, 7],
[7, 4, 2, 1, 7, 1, 1, 1, 0, 5],
[3, 4, 5, 3, 4, 5, 9, 1, 0, 9],
[0, 0, 5, 1, 1, 1, 9, 7, 7, 7]
]
for i in l:
print(i[4])
# or simply use
[i[4] for i in l] #as pointed out by #COLDSPEED
# the above code will create a list with values from 5th column
See it in action here
For a two dimensional array, you can use array[row][column].
I have multidimensional data in a pandas data frame with one variable indicating class. For example here is my attempt with a poor-maps heatmap scatter plot:
import pandas as pd
import random
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.cm import get_cmap
nrows=1000
df=pd.DataFrame([[random.random(), random.random()]+[random.randint(0, 1)] for _ in range(nrows)],
columns=list("ABC"))
bins=np.linspace(0, 1, 20)
df["Abin"]=[bins[i-1] for i in np.digitize(df.A, bins)]
df["Bbin"]=[bins[i-1] for i in np.digitize(df.B, bins)]
g=df.ix[:,["Abin", "Bbin"]+["C"]].groupby(["Abin", "Bbin"])
data=g.agg(["sum", "count"])
data.reset_index(inplace=True)
data["classratio"]=data[("C", "sum")]/data[("C","count")]
plt.scatter(data.Abin, data.Bbin, c=data.classratio, cmap=get_cmap("RdYlGn_r"), marker="s")
I'd like to plot class densities over binned features. Now I used np.digitize for binning and some complicating Python hand-made density calculation to plot a heatmap.
Surely, this can be done more compactly with Pandas (pivot?)? Do you know a neat way to bin the two features (for example 10 bins on the interval 0...1) and then plot a class density heatmap where color indicates the ratio of 1's to total rows within this 2D-bin?
Yep, it can be done in a very concise way using the build in cut function:
In [65]:
nrows=1000
df=pd.DataFrame([[random.random(), random.random()]+[random.randint(0, 1)] for _ in range(nrows)],
columns=list("ABC"))
In [66]:
#This does the trick.
pd.crosstab(np.array(pd.cut(df.A, 20)), np.array(pd.cut(df.B, 20))).values
Out[66]:
array([[2, 2, 2, 2, 7, 2, 3, 5, 1, 4, 2, 2, 1, 3, 2, 1, 7, 2, 4, 2],
[1, 2, 4, 2, 0, 3, 3, 3, 1, 1, 2, 1, 4, 3, 2, 1, 1, 2, 2, 1],
[0, 4, 1, 3, 1, 3, 2, 5, 2, 3, 1, 1, 1, 4, 2, 3, 6, 5, 2, 2],
[5, 2, 3, 2, 2, 1, 3, 2, 4, 0, 3, 2, 0, 4, 3, 2, 1, 3, 1, 3],
[2, 2, 4, 1, 3, 2, 2, 4, 1, 4, 3, 5, 5, 2, 3, 3, 0, 2, 4, 0],
[2, 3, 3, 5, 2, 0, 5, 3, 2, 3, 1, 2, 5, 4, 4, 3, 4, 3, 6, 4],
[3, 2, 2, 4, 3, 3, 2, 0, 0, 4, 3, 2, 2, 5, 4, 0, 1, 2, 2, 3],
[0, 0, 4, 4, 3, 2, 4, 6, 4, 2, 0, 5, 2, 2, 1, 3, 4, 4, 3, 2],
[3, 2, 2, 3, 4, 2, 1, 3, 1, 3, 4, 2, 4, 3, 2, 3, 2, 3, 4, 4],
[0, 1, 1, 4, 1, 4, 3, 0, 1, 1, 1, 2, 6, 4, 3, 5, 3, 3, 1, 4],
[2, 2, 4, 1, 3, 4, 1, 2, 1, 3, 3, 3, 1, 2, 1, 5, 2, 1, 4, 3],
[0, 0, 0, 4, 2, 0, 2, 3, 2, 2, 2, 4, 4, 2, 3, 2, 1, 2, 1, 0],
[3, 3, 0, 3, 1, 5, 1, 1, 2, 5, 6, 5, 0, 0, 3, 2, 1, 5, 7, 2],
[3, 3, 2, 1, 2, 2, 2, 2, 4, 0, 1, 3, 3, 1, 5, 6, 1, 3, 2, 2],
[3, 0, 3, 4, 3, 2, 1, 4, 2, 3, 4, 0, 5, 3, 2, 2, 4, 3, 0, 2],
[0, 3, 2, 2, 1, 5, 1, 4, 3, 1, 2, 2, 3, 5, 1, 2, 2, 2, 1, 2],
[1, 3, 2, 1, 1, 4, 4, 3, 2, 2, 5, 5, 1, 0, 1, 0, 4, 3, 3, 2],
[2, 2, 2, 1, 1, 3, 1, 6, 5, 2, 5, 2, 3, 4, 2, 2, 1, 1, 4, 0],
[3, 3, 4, 7, 0, 2, 6, 4, 1, 3, 4, 4, 1, 4, 1, 1, 2, 1, 3, 2],
[3, 6, 3, 4, 1, 3, 1, 3, 3, 1, 6, 2, 2, 2, 1, 1, 4, 4, 0, 4]])
In [67]:
abins=np.linspace(df.A.min(), df.A.max(), 21)
bbins=np.linspace(df.B.min(), df.B.max(), 21)
Z=pd.crosstab(np.array(pd.cut(df.ix[df.C==1, 'A'], abins)),
np.array(pd.cut(df.ix[df.C==1, 'B'], bbins)), aggfunc=np.mean).div(
pd.crosstab(np.array(pd.cut(df.A, abins)),
np.array(pd.cut(df.B, bbins)), aggfunc=np.mean)).values
Z = np.ma.masked_where(np.isinf(Z),Z)
x=np.linspace(df.A.min(), df.A.max(), 20)
y=np.linspace(df.B.min(), df.B.max(), 20)
X,Y=np.meshgrid(x, y)
plt.contourf(X, Y, Z, vmin=0, vmax=1)
plt.colorbar()
plt.pcolormesh(X, Y, Z, vmin=0, vmax=1)
plt.colorbar()