Python, NumPy и массивы - умножение / деление массива в моей функции - PullRequest
0 голосов
/ 18 октября 2018

Я отредактировал этот пост, чтобы упростить ситуацию, но оригинал ниже.

Я в основном хочу сделать некоторую математику для массива, который имеет такое же количество столбцов, но разные строки для ряда входов.Так что сделайте вычисление, используя входной массив столбцов (1 строка), где вычисления применяются построчно для большего массива.Массив большего размера имеет то же количество столбцов, что и входные.Количество столбцов будет варьироваться в зависимости от того, какие вычисления я делаю, но два входа всегда будут иметь одинаковое количество столбцов;например, массив 1 равен (2000L, 3L), массив 2 будет (1L, 3L), а если массив 1 равен (3050L, 5L), массив 2 (1L, 5L) и так далее.

Вот пример, который я сейчас пробую:

# Make data (for 3 components):
K1, K2, K3 = 30., 16., 36.

G1, G2, G3 = 12., 15., 44.

G = np.array([[G1, G2, G3]])
K = np.array([[K1, K2, K3]])
# Fake data:
fracs = np.array([[0.3,0.6,0.1],[0.5,0.3,0.2],[0.6,0.0,0.4],[0.2,0.8,0.0],[0.1,0.3,0.6]])

def reuss(fracs, K, G):
    rK = 1.0 / (np.sum(fracs/K))
    rG = 1.0 / (np.sum(fracs/G))
    return rK, rG
# Do the function
Kr, Gr = reuss(fracs, K, G)

Что дает мне:

In[]: fracs
Out[]: 
array([[ 0.3,  0.6,  0.1],
       [ 0.5,  0.3,  0.2],
       [ 0.6,  0. ,  0.4],
       [ 0.2,  0.8,  0. ],
       [ 0.1,  0.3,  0.6]])
In[]: K, G
Out[]: (array([[  30., 16., 36.]]), array([[  12., 15., 44.]]))
In[]: Kr, Gr
Out[]: (nan, nan)

Я знаю, что вы можете транслировать скаляры, но что яхочу сделать, это иметь одну функцию, которая позволит мне транслировать массив входов.

ОРИГИНАЛЬНАЯ ПОЧТА ЗДЕСЬ ДЛЯ ПОЛНОСТИв скале.На данный момент я очень долго писал это для системы n фракций и n минеральных фаз.Это мой вставленный код (который очень плохой):

# Reuss isostress bound

def reuss3(K1, G1, K2=None, G2=None, K3=None, G3=None, PHI, f1=1.0, f2=None, f3=None, Kf, Gf=None):
'''
Calculates the Reuss lower bound of Bulk and Shear Moduli. 
Also known as the isostress bound. Represents a suspension of grains.
Default assumes 1 rock phase, this function can be expanded to 3. 

Form taken from Mavko et.al (2009) p.174 

Arguments:
K# = Effective Bulk modulus of phase # in GPa
G# = Effective Shear modulus of phase # in GPa
PHI = Porosity fraction of mixture
f# = Fraction of phase #, default is 100% of phase 1
Kf, Gf = Moduli of fluid, default assumes fluid has 0 shear modulus

Results: 
Kr = Reuss bound of Bulk modulus in GPa
Gr = Reuss bound of Shear modulus in GPa
'''
Kr = 1. /( (((1.-PHI)/K1)*f1) + (((1.-PHI)/K2)*f2) + (((1.-PHI)/K3)*f3) + (PHI/Kf) )
Gr = 1. /( (((1.-PHI)/G1)*f1) + (((1.-PHI)/G2)*f2) + (((1.-PHI)/G3)*f3) + (PHI/Gf) )
return Kr, Gr

Я пытался улучшить это и на самом деле моделировать среднее значение по Ройсу для реальных пород по их известному составу, пористости и водонасыщенности.Мои входные данные для этого представляют собой серию минеральных фракций, которые составляют 1 пробу в измерении глубины, поэтому в основном это двумерный массив с ( n выборок, n фаз).Я понятия не имею, как взять массив свойств минералов в одномерном массиве ( n фаз) и выполнить расчет для каждого образца глубины.До сих пор я пробовал это, которое выдает данные nan:

# Make data (for 3 components):
K1, K2, K3 = 30., 16., 36.

G1, G2, G3 = 12., 15., 44.

G = np.array([[G1, G2, G3]])
K = np.array([[K1, K2, K3]])
# Fake data:
fracs = np.array([[0.3,0.6,0.1],[0.5,0.3,0.2],[0.6,0.0,0.4],[0.2,0.8,0.0],[0.1,0.3,0.6]])

def reuss(fracs, K, G):
    rK = 1.0 / (np.sum(fracs/K))
    rG = 1.0 / (np.sum(fracs/G))
    return rK, rG
# Do the function
rK, rG = reuss(fracs, K, G)

Я полагаю, что с формой массивов что-то не так, хотя мне нужен совет о том, как двигаться дальше с этим.

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

Я интерпретировал ваш вопрос, поскольку число строк является переменным, поэтому ваш выходной массив должен быть одномерным массивом, длина которого равна числу строк.По сути, вы делаете точечное произведение между каждой строкой fracs[i] (3d) и вектором 1/K (или 1/G) (3d) для каждой из 5 строк, а затем делаете 5 сумм.Это правильно?

Если это так, я думаю, что ваш написанный код будет суммироваться по неправильной оси.Должно быть так:

def reuss(fracs, K, G): # You want 5 outputs for rK and rG, right? 
    rK = 1 / np.sum(fracs / K, axis = 1) # I interpret this as what you want. 
    rG = 1 / np.sum(fracs / G, axis = 1)
    return rK, rG

# alternatively you can stack K and G and do it all at once 
rK,rG = (1/((fracs[...,np.newaxis]/np.stack((K,G),-1)[np.newaxis,...]).sum(axis=1))).T

В любом случае возвращается

>>> reuss(fracs,K,G)
(array([19.88950276, 24.40677966, 32.14285714, 17.64705882, 25.80645161]),
 array([14.86486486, 15.10297483, 16.92307692, 14.28571429, 23.8267148 ]))

edit: это без дополнительной оси в вашем определении K и G.Вы пишете np.array([[K1,K2,K3]]).Я пишу np.array([K1,K2,K3]).

0 голосов
/ 19 октября 2018

Когда я запускаю оба ваших фрагмента, это работает правильно.Вы можете попробовать это снова?Если он по-прежнему не работает, сообщите нам свои версии на python и numpy.

Примечание: единственный фрагмент кода, который НЕ РАБОТАЕТ, это тот, который вы используете, потому что у PHI нет значения по умолчанию и он следует аргументамсо значениями по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...