Python 中所有符号的变化
我已经完成了这个函数 changesOfSign
,它接受一个矩阵作为参数,并返回该矩阵,该矩阵的行是原始行与 +
或 的所有可能组合- 与条目关联的
符号:
import itertools
import numpy as np
def expandgrid(*itrs): # https://stackoverflow.com/a/12131385/1100107
product = list(itertools.product(*itrs))
return [[x[i] for x in product] for i in range(len(itrs))]
def changesOfSign(mat):
maps = np.apply_along_axis(
lambda r: map(lambda x: [0] if x==0 else [-x,x], r),
1, mat
)
lists = [list(m) for m in maps]
mats = [np.transpose(expandgrid(*lists[i])) for i in range(len(lists))]
return np.vstack(tuple(mats))
arr = np.array([
[1, 0, 3],
[5, 2, 4]
])
例如:
changesOfSign(arr)
Out[22]:
array([[-1, 0, -3],
[-1, 0, 3],
[ 1, 0, -3],
[ 1, 0, 3],
[-5, -2, -4],
[-5, -2, 4],
[-5, 2, -4],
[-5, 2, 4],
[ 5, -2, -4],
[ 5, -2, 4],
[ 5, 2, -4],
[ 5, 2, 4]])
现在我想概括此函数,以便可以选择我想要更改符号的列。我已经完成了:
cols = [0, 1] # columns for which changes of sign are desired
lists = np.apply_along_axis(
lambda r: [[x] if (x==0 or i not in cols) else [-x,x] for i,x in enumerate(r)],
1, arr
)
mats = [np.transpose(expandgrid(*lists[i])) for i in range(len(lists))]
np.vstack(tuple(mats))
它有效:
array([[-1, 0, 3],
[ 1, 0, 3],
[-5, -2, 4],
[-5, 2, 4],
[ 5, -2, 4],
[ 5, 2, 4]])
但是当我运行np.apply_along_axis
时我收到此警告:
VisibleDeprecationWarning:不推荐从不规则的嵌套序列(这是具有不同长度或形状的列表或元组或 ndarray 的列表或元组)创建 ndarray 。如果您打算这样做,则必须在创建 ndarray 时指定“dtype=object”。
我不知道可以将 dtype=object
放在哪里。有什么想法吗?
编辑
我有一个解决方案:
def f(cols):
return lambda r: [[x] if (x==0 or i not in cols) else [-x,x] for i,x in enumerate(r)]
lists = [f(cols)(r) for r in arr]
mats = [np.transpose(expandgrid(*lists[i])) for i in range(len(lists))]
np.vstack(tuple(mats))
I've done this function, changesOfSign
, which takes as argument a matrix and returns the matrix whose rows are all possible combinations of the original rows with the +
or -
sign associated to the entries:
import itertools
import numpy as np
def expandgrid(*itrs): # https://stackoverflow.com/a/12131385/1100107
product = list(itertools.product(*itrs))
return [[x[i] for x in product] for i in range(len(itrs))]
def changesOfSign(mat):
maps = np.apply_along_axis(
lambda r: map(lambda x: [0] if x==0 else [-x,x], r),
1, mat
)
lists = [list(m) for m in maps]
mats = [np.transpose(expandgrid(*lists[i])) for i in range(len(lists))]
return np.vstack(tuple(mats))
arr = np.array([
[1, 0, 3],
[5, 2, 4]
])
For example:
changesOfSign(arr)
Out[22]:
array([[-1, 0, -3],
[-1, 0, 3],
[ 1, 0, -3],
[ 1, 0, 3],
[-5, -2, -4],
[-5, -2, 4],
[-5, 2, -4],
[-5, 2, 4],
[ 5, -2, -4],
[ 5, -2, 4],
[ 5, 2, -4],
[ 5, 2, 4]])
Now I want to generalize this function to have the possibility to choose for which columns I want the changes of sign. I've done:
cols = [0, 1] # columns for which changes of sign are desired
lists = np.apply_along_axis(
lambda r: [[x] if (x==0 or i not in cols) else [-x,x] for i,x in enumerate(r)],
1, arr
)
mats = [np.transpose(expandgrid(*lists[i])) for i in range(len(lists))]
np.vstack(tuple(mats))
It works:
array([[-1, 0, 3],
[ 1, 0, 3],
[-5, -2, 4],
[-5, 2, 4],
[ 5, -2, 4],
[ 5, 2, 4]])
but I have this warning when I run np.apply_along_axis
:
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.
I don't know where I can put dtype=object
. Any idea?
EDIT
I have a solution:
def f(cols):
return lambda r: [[x] if (x==0 or i not in cols) else [-x,x] for i,x in enumerate(r)]
lists = [f(cols)(r) for r in arr]
mats = [np.transpose(expandgrid(*lists[i])) for i in range(len(lists))]
np.vstack(tuple(mats))
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是我的解决方案。为所有列设置
cols=None
(默认)。Here is my solution. Set
cols=None
(default) for all columns.