Python 中所有符号的变化

发布于 2025-01-12 08:28:18 字数 2135 浏览 0 评论 0原文

我已经完成了这个函数 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

转身泪倾城 2025-01-19 08:28:18

这是我的解决方案。为所有列设置 cols=None (默认)。

def changesOfSign(mat, cols=None):
    def f(r):
        return (
            [[x] if (x==0 or i not in cols) else [-x,x] 
             for i,x in enumerate(r)]
        )
    def g(r):
        return (
            [[0] if x==0 else [-x,x] for x in r]
        )
    h = g if cols is None else f
    lists = [h(r) for r in mat]
    mats = [np.transpose(expandgrid(*l)) for l in lists]
    return np.vstack(tuple(mats))

Here is my solution. Set cols=None (default) for all columns.

def changesOfSign(mat, cols=None):
    def f(r):
        return (
            [[x] if (x==0 or i not in cols) else [-x,x] 
             for i,x in enumerate(r)]
        )
    def g(r):
        return (
            [[0] if x==0 else [-x,x] for x in r]
        )
    h = g if cols is None else f
    lists = [h(r) for r in mat]
    mats = [np.transpose(expandgrid(*l)) for l in lists]
    return np.vstack(tuple(mats))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文