#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-частью.