Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
981 views
in Technique[技术] by (71.8m points)

array in array to array in numpy

Dear friends in stack overflow, I have trouble calculation with Numpy and Sympy. A is defined by

import numpy as np
import sympy as sym

sym.var('x y')
f = sym.Matrix([0,x,y])
func = sym.lambdify( (x,y), f, "numpy")

X=np.array([1,2,3])
Y=np.array((1,2,3])

A = func(X,Y).

Here, X and Y are just examples. In general, X and Y are one dimensional array in numpy, and they have the same length. Then, A’s output is

array([[0],
       [array([1, 2, 3])],
       [array([1, 2, 3])]], dtype=object).

But, I'd like to get this as

np.array([[0,0,0],[1,2,3],[1,2,3]]).

If we call this B, How do you convert A to B automatically. B’s first column is filled by 0, and it has the same length with X and Y.

Do you have any ideas?

question from:https://stackoverflow.com/questions/65857957/array-in-array-to-array-in-numpy

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First let's make sure we understand what is happening:

In [52]: x, y = symbols('x y')
In [54]: f = Matrix([0,x,y])
    ...: func = lambdify( (x,y), f, "numpy")
In [55]: f
Out[55]: 
?0?
? ?
?x?
? ?
?y?

In [56]: print(func.__doc__)
Created with lambdify. Signature:

func(x, y)

Expression:

Matrix([[0], [x], [y]])

Source code:

def _lambdifygenerated(x, y):
    return (array([[0], [x], [y]]))

See how the numpy function looks just like the sympy, replacing sym.Matrix with np.array. lambdify just does a lexographic translation; it does not have a deep knowledge of the differences between the languages.

With scalars the func runs as expected:

In [57]: func(1,2)
Out[57]: 
array([[0],
       [1],
       [2]])

With arrays the results is this ragged array (new enough numpy adds this warning:

In [59]: func(np.array([1,2,3]),np.array([1,2,3]))
<lambdifygenerated-2>:2: 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
  return (array([[0], [x], [y]]))
Out[59]: 
array([[0],
       [array([1, 2, 3])],
       [array([1, 2, 3])]], dtype=object)

If you don't know numpy, sympy is not a short cut to filling in your knowledge gaps.

The simplest fix is to replace original 0 with another symbol.

Even in sympy, the 0 is not expanded:

In [65]: f.subs({x:Matrix([[1,2,3]]), y:Matrix([[4,5,6]])})
Out[65]: 
?    0    ?
?         ?
?[1  2  3]?
?         ?
?[4  5  6]?

In [74]: Matrix([[0,0,0],[1,2,3],[4,5,6]])
Out[74]: 
?0  0  0?
?       ?
?1  2  3?
?       ?
?4  5  6?

In [75]: Matrix([[0],[1,2,3],[4,5,6]])
...
ValueError: mismatched dimensions

To make the desired array in numpy we have to do something like:

In [71]: arr = np.zeros((3,3), int)
In [72]: arr[1:,:] = [[1,2,3],[4,5,6]]
In [73]: arr
Out[73]: 
array([[0, 0, 0],
       [1, 2, 3],
       [4, 5, 6]])

That is, initial the array and fill selected rows. There isn't simple expression that will do the desired 'automaticlly fill the first row with 0', much less something that can be naively translated from sympy.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...