Как перетасовать крошечные сферы внутри большой сферы способом pythoni c? - PullRequest
0 голосов
/ 06 августа 2020

У меня есть список сфер с некоторыми известными характеристиками (идентификаторы, радиусы, массы и позиции) с идентификаторами , радиусами и массами , являющимися 1D массивы с формой (511,) и положениями является 3D массив с формой (511, 3) внутри некоторого большого сферического объема с известным центром, ( 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 прежде чем что-то с ними делать ? (Мне действительно нужна информация о моем первоначальном населении для дальнейшего использования, поэтому я не могу ее игнорировать)

1 Ответ

1 голос
/ 13 августа 2020

Лучшим подходом было бы вычисление ваших ограничений в векторизованном формате (который очень эффективен в numpy) вместо использования для l oop. Затем сгенерируйте массив индексов, соответствующих вашим ограничениям, и затем перемешайте эти индексы.

Итак, используя данные из вашего примера выше:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...