在Python中将2D数组的平均值计算为距中心的距离的函数

时间:2018-07-05 14:02:21

标签: python numpy

我正在尝试计算数量(以2D数组的形式)的平均值,作为其距2D网格中心的距离的函数。我知道我的想法是我确定所有与中心距离R的数组元素,然后将它们相加并除以元素数。但是,我很难确定要执行此操作的算法。

我已附上代码的一个工作示例,以生成下面的2d数组。该代码用于计算重力透镜产生的一些量,因此该阵列的制造方式与该问题无关,但是我附加了整个代码,以便可以创建用于测试的输出阵列。

import numpy as np
import multiprocessing
import matplotlib.pyplot as plt
n = 100 # grid size

c = 3e8
G = 6.67e-11
M_sun = 1.989e30
pc = 3.086e16  # parsec
Dds = 625e6*pc          
Ds = 1726e6*pc #z=2
Dd = 1651e6*pc #z=1

FOV_arcsec = 0.0001
FOV_arcmin = FOV_arcsec/60.   


pix2rad = ((FOV_arcmin/60.)/float(n))*np.pi/180.
rad2pix = 1./pix2rad

Renorm = (4*G*M_sun/c**2)*(Dds/(Dd*Ds))
#stretch = [10, 2]




# To create a random distribution of points
def randdist(PDF, x, n):
    #Create a distribution following PDF(x). PDF and x
    #must be of the same length. n is the number of samples
    fp = np.random.rand(n,)
    CDF = np.cumsum(PDF)
    return np.interp(fp, CDF, x)


def get_alpha(args):    
    zeta_list_part, M_list_part, X, Y = args
    alpha_x = 0
    alpha_y = 0
    for key in range(len(M_list_part)):
        z_m_z_x = (X - zeta_list_part[key][0])*pix2rad
        z_m_z_y = (Y - zeta_list_part[key][1])*pix2rad
        alpha_x += M_list_part[key] * z_m_z_x / (z_m_z_x**2 + z_m_z_y**2)
        alpha_y += M_list_part[key] * z_m_z_y / (z_m_z_x**2 + z_m_z_y**2)
    return (alpha_x, alpha_y)

if __name__ == '__main__':
    # number of processes, scale accordingly
    num_processes = 1 # Number of CPUs to be used
    pool = multiprocessing.Pool(processes=num_processes)
    num = 100 # The number of points/microlenses
    r = np.linspace(-n, n, n)
    PDF = np.abs(1/r)
    PDF = PDF/np.sum(PDF)    # PDF should be normalized
    R = randdist(PDF, r, num)
    Theta = 2*np.pi*np.random.rand(num,)
    x1= [R[k]*np.cos(Theta[k])*1 for k in range(num)]
    y1 = [R[k]*np.sin(Theta[k])*1 for k in range(num)]
    # Uniform distribution
    #R = np.random.uniform(-n,n,num)
    #x1= np.random.uniform(-n,n,num)
    #y1 = np.random.uniform(-n,n,num)
    zeta_list = np.column_stack((np.array(x1), np.array(y1))) # List of coordinates for the microlenses 
    x = np.linspace(-n,n,n)
    y = np.linspace(-n,n,n)
    X, Y = np.meshgrid(x,y)
    M_list = np.array([0.1 for i in range(num)])
    # split zeta_list, M_list, X, and Y
    zeta_list_split = np.array_split(zeta_list, num_processes, axis=0)
    M_list_split = np.array_split(M_list, num_processes)
    X_list = [X for e in range(num_processes)]  
    Y_list = [Y for e in range(num_processes)]

    alpha_list = pool.map(
            get_alpha, zip(zeta_list_split, M_list_split, X_list, Y_list))
    alpha_x = 0
    alpha_y = 0
    for e in alpha_list:
        alpha_x += e[0] 
        alpha_y += e[1] 

alpha_x_y = 0
alpha_x_x = 0
alpha_y_y = 0
alpha_y_x = 0
alpha_x_y, alpha_x_x = np.gradient(alpha_x*rad2pix*Renorm,edge_order=2)
alpha_y_y, alpha_y_x = np.gradient(alpha_y*rad2pix*Renorm,edge_order=2) 
det_A = 1 - alpha_y_y - alpha_x_x + (alpha_x_x)*(alpha_y_y) - (alpha_x_y)*(alpha_y_x)
abs = np.absolute(det_A)
I = abs**(-1.)  
O = np.log10(I+1)
plt.contourf(X,Y,O,100)

感兴趣的数组是O,我已经附上了它的外观图。根据点的随机分布,它可以不同。 enter image description here

我要做的是绘制O的平均值,该平均值作为距网格中心的半径的函数。最后,我希望能够在2d线图中绘制平均O与距中心的距离的函数。因此,我想第一步是基于X和Y定义半径为R的圆。

def circle(x,y):
    r = np.sqrt(x**2 + y**2)
    return r 

现在,我只需要找出一种方法来查找O的所有值,这些值与R的等效值具有相同的索引。在这部分上,Kinda感到困惑,不胜感激。

1 个答案:

答案 0 :(得分:2)

您可以找到以(0,0)为中心,半径为R的圆的几何坐标,如下所示:

phi = np.linspace(0, 1, 50)
x = R*np.cos(2*np.pi*phi)
y = R*np.sin(2*np.pi*phi)
然而,这些值将不会落在常规像素网格上,而是介于两者之间。

为了将它们用作采样点,您可以对值进行取整并将其用作索引,也可以对附近像素的值进行插值。

注意:像素索引与xy不同。在您的示例中,(0,0)位于图片位置(50,50)