在圆柱面上生成网格并将数据存储到其中

时间:2017-10-05 06:31:13

标签: python pandas numpy binning

我不确定如何在Python中解决以下问题:
我有一个圆柱面,我希望mesh然后bin数据到网格的每个块。我有射击圆柱面的光线的位置数据(X,Y,Z)。在圆柱体上生成网格后,我必须计算网格的每个块中的光线数量(数据点)。

气缸的参数如下:
半径= 0.1m,高度= 0.15m,中点:[X = 0,Y = 0,Z = 0]

要生成网格,可以使用How to generate regular points on cylindrical surface中的答案,其代码复制如下: `

import numpy as np
def make_cylinder(radius, length, nlength, alpha, nalpha, center, orientation):
"""
radius = radius of cylinder,
length = cylinder height, nlength = number of lengthwise divisions.
alpha = total degrees of cylinder, nalpha = number of circumferential divisions.
center = [X,Y,Z] coordinates of cylinder's midpoint.

"""
#Create the length array
I = np.linspace(0, length, nlength)
#Create alpha array avoid duplication of endpoints
#Conditional should be changed to meet your requirements
if int(alpha) == 360:
    A = np.linspace(0, alpha, num=nalpha, endpoint=False)/180*np.pi
else:
    A = np.linspace(0, alpha, num=nalpha)/180*np.pi

#Calculate X and Y
X = radius * np.cos(A)
Y = radius * np.sin(A)

#Tile/repeat indices so all unique pairs are present
pz = np.tile(I, nalpha)
px = np.repeat(X, nlength)
py = np.repeat(Y, nlength)

points = np.vstack(( pz, px, py )).T

#Shift to center
shift = np.array(center) - np.mean(points, axis=0)
points += shift

#Orient tube to new vector
#Grabbed from an old unutbu answer
def rotation_matrix(axis,theta):
    a = np.cos(theta/2)
    b,c,d = -axis*np.sin(theta/2)
    return np.array([[a*a+b*b-c*c-d*d, 2*(b*c-a*d), 2*(b*d+a*c)],
                     [2*(b*c+a*d), a*a+c*c-b*b-d*d, 2*(c*d-a*b)],
                     [2*(b*d-a*c), 2*(c*d+a*b), a*a+d*d-b*b-c*c]])

ovec = orientation / np.linalg.norm(orientation)
cylvec = np.array([1,0,0])

if np.allclose(cylvec, ovec):
    return points

#Get orthogonal axis and rotation
oaxis = np.cross(ovec, cylvec)
rot = np.arccos(np.dot(ovec, cylvec))

R = rotation_matrix(oaxis, rot)
return points.dot(R)

` 现在剩下的就是遍历" Ray数据"找到击中网格的每个块的光线数量。

我最初的思考过程如下:

data = np.genfromtxt('ray_data.csv', delimiter=',') 
num_data_rows, num_data_cols = np.shape(data)

for i in range (num_data_rows): #Loop through the data

这是我被困的地方。如上所述," Ray Data"是一个CSV文件,包含撞击圆柱面的每条光线的位置(X,Y,Z)。请参阅提供的链接:Ray data sample for cylindrical surface

我只需要弄清楚如何检查光线在网格中的位置。 每个块中的光线数量将乘以常数(每条光线的功率),以获得每个块中的功率(以瓦特为单位)。然后将该值除以块的面积以获得热通量(W / m ^ 2)。

我需要的最终输出是一个数组,其中包含每个网格块的质心以及相应的热通量值。

任何想法如何解决这个问题? 我相信与pandas合作也是一种选择。

1 个答案:

答案 0 :(得分:0)

正如评论中已经提出的,我建议将表面转换为2d空间。这样,您就可以轻松地对数据进行分组。

import numpy as np
import pandas as pd

# generate some random rays (for which we will just assume they hit the surface)

rays = pd.DataFrame(
  np.random.uniform(-1,1,(8000,4)),
  columns=["x", "y", "z", "intensity"]
)

# transform x and y to polar coordinates while dropping the radius
# (again, just assuming they hit the surface)

rays["phi"] = rays.T.apply(lambda row: np.arctan2(row.y, row.x)).T

rays.head()现在看起来如下所示。 zphi代表2d中的光线。 intensity就是你所谓的“射线之力”。

x         y         z  intensity       phi
0 -0.237026 -0.634709 -0.889694   0.362156 -1.928199
1 -0.481137 -0.446912  0.687224   0.268080 -2.393056
2 -0.805538  0.068678  0.272009   0.990947  3.056541
3  0.549282 -0.330665  0.318683  -0.150776 -0.541886
4 -0.215676 -0.030922 -0.478929   0.408720 -2.999190

现在,只需创建分档并对数据进行分组。最后总结所有强度。

z_bins = np.arange(0, 1, .1)
phi_bins = np.arange(-np.pi, np.pi, np.pi/10)

result = rays.groupby([
  pd.cut(rays.phi, phi_bins), 
  pd.cut(rays.z, z_bins), 
]).intensity.sum()

result.head()然后如下所示:

phi               z         
(-3.142, -2.827]  (0, 0.1]      0.719154
                  (0.1, 0.2]   -1.733479
                  (0.2, 0.3]    2.073013
                  (0.3, 0.4]    1.967453
                  (0.4, 0.5]    0.001312