не удается запустить python/numpy lin-alg из SQL : Ошибка типа: Нет цикла, соответствующего указанной подписи и приведению

#python #sql #numpy

Вопрос:

Вот код, который я пытаюсь запустить из SQL

 declare @pscript nvarchar(max),@sqlscript nvarchar(max);
set @sqlscript=N'select sku,min_price,med_price,max_price,min_vol,med_vol,max_vol from 
py_alg';
set @pscript=N'
import numpy as np
df1 = InputDataSet
df2 = df1
a = df1["min_price"]
a = np.array(a, dtype = float)
b = df1["med_price"]
b = np.array(b, dtype = float)
c = df1["max_price"]
c = np.array(c, dtype = float)
x = df1["min_vol"]
x = np.array(x, dtype = float)
y = df1["med_vol"]
y = np.array(y, dtype = float)
z = df1["max_vol"]
z = np.array(z, dtype = float)
a1 = [[a * a, a, 1], [b * b, b, 1], [c * c, c, 1]]
b1 = [x, y, z]
result = np.linalg.inv(a1).dot(b1)
df2["a_val"] = result[0]
df2["b_val"] = result[1]
df2["c_val"] = result[2]
OutputDataSet = df2[["sku","a_val","b_val","c_val"]]';
Exec sp_execute_external_script
@language = N'Python',
@script = @pscript,
@input_data_1 = @sqlscript

GO
 

в этом и заключается ошибка:

 Error in execution.  Check the output for more information.
Traceback (most recent call last):
  File "<string>", line 5, in <module>
  File "C:PROGRA~1MICROS~4MSSQL1~1.SQLMSSQLEXTENS~1SQL2017018EB41034-C5CC-4E7B-83FD-ACD4781832F6sqlindb.py", line 63, in transform
    result = np.linalg.inv(a1).dot(b1)
  File "C:Program FilesMicrosoft SQL ServerMSSQL14.SQL2017PYTHON_SERVICESlibsite-packagesnumpylinalglinalg.py", line 526, in inv
    ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj)
TypeError: No loop matching the specified signature and casting
was found for ufunc inv
 

Попытался понизить numpy до более низкой версии 1.xx.xx, как было предложено на форуме, но не смог этого сделать.

вот таблица данных :

 sku min_price   med_price   max_price   min_vol med_vol max_vol
1   0.99    1.99    2.99    60  51  20
2   300 400 500 2000    1500    1000
3   100 150 200 1000    600 400
4   89  150 210 5000    3000    1500
5   45  60  99  1500    900 700
 

любая помощь, пожалуйста

Я работаю над определением кривой спроса с использованием квадратного уравнения, вот ссылка на эту тему http://www.silota.com/docs/recipes/sql-estimating-demand-curves-optimizing-pricing.html

Я написал этот код на python,чтобы добиться того же самого и обновить значения a,b, c в таблице SQL, которая работает:

 import pyodbc
import numpy as np

connstring = (
"Driver={SQL Server Native Client 11.0};"
"Server=[servername];"
"Database=DBM;"
"Trusted_Connection=yes;"
)

conn = pyodbc.connect(connstring)
conn2 = pyodbc.connect(connstring)


cursor = conn.cursor()
cursor2 = conn2.cursor()

cursor.execute("select 
sku,min_price,med_price,max_price,min_vol,med_vol,max_vol from py_alg")
for row in cursor:

a1 = [[row[1] * row[1], row[1], 1], [row[2] * row[2], row[2], 1], 
[row[3] * row[3], row[3], 1]]
b1 = [row[4], row[5], row[6]]
result = np.linalg.inv(a1).dot(b1)

cursor2.execute("update py_alg set a_val=?, b_val=?, c_val=? where 
sku=?;", (result[0], result[1], result[2],
                                                                              
row[0], ))
conn2.commit()
conn.close()
conn2.close()
 

Но хотел выполнить ту же операцию, вызвав хранимую процедуру SQL

Комментарии:

1. Похоже , у него проблемы с a1 переменной в np.linalg.inv(a1) , это список списков. Я предполагаю a , b , c являются массивами 1d. Проверять np.array(a1) . Я не думаю, что это будет 2d (или даже 3d) числовой массив.

2. Я понятия не имею, что должно делать понижение рейтинга numpy!

Ответ №1:

Посмотрите, что происходит, когда я пытаюсь сделать часть a1 переменной из массива из 5 элементов a :

 In [86]: a = np.array([1,2,3,4,5])
In [87]: np.array([a*a, a, 1])
<ipython-input-87-335032001ded>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  np.array([a*a, a, 1])
Out[87]: 
array([array([ 1,  4,  9, 16, 25]), array([1, 2, 3, 4, 5]), 1],
      dtype=object)
 

Я подозреваю, что вы хотите a1 быть числовым массивом в форме (5,3,3).

 a1 = [[a * a, a, 1], [b * b, b, 1], [c * c, c, 1]]
 

не буду этого делать. Это работает только a в том случае, если b , c являются скалярами, одиночными числами.

Если я определю:

 In [88]: ones = np.ones_like(a)
In [89]: ones
Out[89]: array([1, 1, 1, 1, 1])
 

затем мы можем создать числовой массив:

 In [90]: np.array([a*a, a, ones])
Out[90]: 
array([[ 1,  4,  9, 16, 25],
       [ 1,  2,  3,  4,  5],
       [ 1,  1,  1,  1,  1]])
 

Сделайте это для всего a1 выражения, и результатом будет массив (3,3,5). Ему понадобится a transpose(2,0,1) , чтобы сделать (5,3,3), который inv можно использовать.

Комментарии:

1. спасибо @hpaulj за то, что поделился, попробую. Также добавили еще несколько деталей к моему вопросу, пожалуйста, посмотрите, дает ли это больше ясности

2. Я не собираюсь помогать вам с SQL-частью.