【问题标题】:How to shuffle tiny spheres inside a big sphere in a pythonic way?如何以pythonic的方式在一个大球体内洗牌?
【发布时间】:2020-11-27 00:26:48
【问题描述】:

我有一个具有一些已知特征(id、半径、质量和位置)的球体列表,其中包含 idsradiimasses 是具有形状 (511, ) 的 1D 数组positions 是具有形状 (511, 3) 的 3D 数组 在一些已知的大球形体积内中心,(0, 0, 0) 和半径,distance_max

hal_ids_data = np.array([19895, 19896, ..., 24249])                   
hal_radiuss_data = np.array([1.047, 1.078, ..., 3.263])                 
hal_masss_data = np.array([2.427e+06, 8.268e+06, ..., 8.954e+07]     
hal_positions_data = np.array([np.array([-33.78, 10.4, 33.83]), np.array([-33.61, 6.34, 35.64]), ..., np.array([-0.4014, 4.121, 33.05])])

我想将这些小球随机放置在大球内的整个体积中,同时保持它们各自的特征不变,这意味着只有它们的位置需要被打乱受到如下所示的两个约束

for hal_id, hal_position, hal_radius, hal_mass in zip(hal_ids_data, hal_positions_data, hal_radiuss_data, hal_masss_data):

    # check if 1) any one of the small spheres are above some mass threshold AND 2) inside the big sphere
    if ((np.sqrt(pow(hal_position[0], 2)+pow(hal_position[1], 2)+pow(hal_position[2], 2)) < distance_max) and (log10(hal_mass)>=1e8)):

        # if so, then do the following stuff down here but to the shuffled populations of small spheres meeting the conditions above rather than to the original population

在对它们进行一些操作之前,在最后一个 if statement 下对我的球体进行洗牌的最快和最短方法是什么? (我确实需要我的原始人口信息以供以后使用,所以我不能忽视它)

【问题讨论】:

  • 如果您远离pandas,这可能会更干净/更容易。建议您使用原始数据的一些示例更新帖子,特别是包含“大球体”的变量和带有小球体的列表。另外,如果您要更改位置,则唯一要保留的数据是每个小球体的半径,对吗?所以原来的位置是扔掉的?
  • 我能想到的唯一算法是 POisson 球体采样,citeseerx.ist.psu.edu/viewdoc/… 也许你可以在那里找到有用的东西
  • 您能添加一个您的数据的小例子吗?
  • 看到有建设性的正面/负面反馈而不是简单地“不喜欢”一个帖子,这将是真正的注意。我的理解是,我们千万不能像fb一样对待这种环境。

标签: python-3.x pandas random shuffle


【解决方案1】:

最好的方法是以矢量化格式计算约束(这在 numpy 中非常有效),而不是使用 for 循环。然后生成一个与你的约束匹配的索引数组,然后打乱这些索引。

所以使用上面的示例数据:

import numpy as np

distance_max = 49 #I chose this so that we have some matching items

hal_ids_data = np.array([19895, 19896, 24249])                   
hal_radius_data = np.array([1.047, 1.078, 3.263])                 
hal_mass_data = np.array([2.427e+06, 8.268e+06, 8.954e+07])     
hal_positions_data = np.array([np.array([-33.78, 10.4, 33.83]), np.array([-33.61, 6.34, 35.64]), np.array([-0.4014, 4.121, 33.05])])

# Compute the conditions for every sphere at the same time instead of for loop
within_max = np.sqrt(pow(hal_positions_data[:,0],2) + pow(hal_positions_data[:,1],2) + pow(hal_positions_data[:,2],2)) < distance_max
mass_contraint = np.log10(hal_mass_data) >= 1 #I chose this so that we have some matching items
matched_spheres = within_max & mass_contraint

# Get indexes of matching spheres
idx = np.where(matched_spheres)[0] # create array of indexes
np.random.shuffle(idx) #shuffle array of indexes in place

# Generate shuffled data by applying the idx to the original arrays and saving to new 's_' arrays
s_hal_ids_data = hal_ids_data[idx]
s_hal_radius_data = hal_radius_data[idx]
s_hal_mass_data = hal_mass_data[idx]
s_hal_positions_data = hal_positions_data[idx]

# Do stuff with shuffled population of small spheres

【讨论】:

    猜你喜欢
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多