[英]Calculating mean value of a 2D array as a function of distance from the center in Python
I'm trying to calculate the mean value of a quantity(in the form of a 2D array) as a function of its distance from the center of a 2D grid. 我正在尝试计算数量(以2D数组的形式)的平均值作为其距2D网格中心的距离的函数。 I understand that the idea is that I identify all the array elements that are at a distance R from the center, and then add them up and divide by the number of elements. 我知道我的想法是我确定所有与中心距离R的数组元素,然后将它们相加并除以元素数。 However, I'm having trouble actually identifying an algorithm to go about doing this. 但是,我很难确定要执行此操作的算法。
I have attached a working example of the code to generate the 2d array below. 我已附上代码的工作示例以生成下面的2d数组。 The code is for calculating some quantities that are resultant from gravitational lensing, so the way the array is made is irrelevant to this problem, but I have attached the entire code so that you could create the output array for testing. 该代码用于计算重力透镜产生的一些量,因此该阵列的制造方式与该问题无关,但是我附加了整个代码,以便可以创建用于测试的输出阵列。
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)
The array of interest is O, and I have attached a plot of how it should look like. 感兴趣的数组是O,我附上了它的外观图。 It can be different based on the random distribution of points. 根据点的随机分布,它可以不同。
What I'm trying to do is to plot the mean values of O as a function of radius from the center of the grid. 我想做的是绘制O的平均值,该平均值作为距网格中心的半径的函数。 In the end, I want to be able to plot the average O as a function of distance from center in a 2d line graph. 最后,我希望能够在2d线图中绘制平均O与距中心的距离的函数。 So I suppose the first step is to define circles of radius R, based on X and Y. 因此,我想第一步是基于X和Y定义半径为R的圆。
def circle(x,y):
r = np.sqrt(x**2 + y**2)
return r
Now I just have to figure out a way to find all the values of O, that have the same indices as equivalent values of R. Kinda confused on this part and would appreciate any help. 现在,我只需要找出一种方法来查找所有O值,这些值与R的等效值具有相同的索引。在这部分上,Kinda感到困惑,不胜感激。
You can find the geometric coordinates of a circle with center (0,0)
and radius R as such: 您可以找到具有中心(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)
these values however will not fall on the regular pixel grid but in between. 但是,这些值将不会落在常规像素网格上,而是介于两者之间。
In order to use them as sampling points you can either round the values and use them as indexes or interpolate the values from the near pixels. 为了将它们用作采样点,您可以对值进行取整并将其用作索引,也可以对附近像素的值进行插值。
Attention: The pixel indexes and the x
, y
are not the same. 注意:像素索引与x
, y
不同。 In your example (0,0)
is at the picture location (50,50)
. 在您的示例中(0,0)
在图片位置(50,50)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.