Numpy 索引表达式中的速记自引用

Shorthand self reference in Numpy indexing expressions

提问人:Michael Sweet 提问时间:6/27/2023 最后编辑:Michael Sweet 更新时间:7/12/2023 访问量:66

问:

有没有更有效的方法在 NumPy 数组索引表达式中引用外部数组?我经常发现,对于冗长命名的 NumPy 数组,索引表达式很快就会变得非常丑陋。例如:

other_precice_array = precicely_named_array[(precicely_named_array > num) | (precicely_named_array.isodd())]

对我来说,使用三个“precicely_named_array”的引用似乎有点不合时宜。我真的希望能够在索引时以速记方式引用数组,如下所示:

other_precice_array = precicely_named_array[(self > num) | (self.isodd())]

other_precice_array = precicely_named_array[(np.me > num) | (np.me.isodd())]

这种语法还有一个额外的好处,即当被切片的数组依赖于不同的数组时,它更加明显。看:

other_precice_array = precicely_named_array[(different_array > num) | (self.isodd())]

有什么办法可以做到吗?或者我缺少为什么我真的不想要这个的原因?

我认为像np.where和np.choose这样的函数可能会提供解决方案,但它们仍然需要对切片数组的多次引用。

P.S. 我意识到还有其他方法可以使表达式更简洁,例如将切片表达式分离到它自己的变量中,或者只是使用更短的名称,但出于这个问题的目的,我对这些答案不感兴趣。

python numpy 自我 简写

评论

2赞 Barmar 6/27/2023
我不这么认为。你可以只使用一个较短的变量名称,这样它就不会那么冗长了。你可以做,然后在索引内使用。this = precisely_named_arraythis
1赞 hpaulj 6/27/2023
请记住,运行此操作的是 Python。 是一个 numpy 索引调用,但首先进行完整评估。如果 是 ,则首先计算这些项中的每一个。 不会更改 Python 语法或计算顺序。x[z]zz(a | b)numpy
0赞 juanpa.arrivillaga 6/27/2023
只需使用另一个名称较短的变量,就没有“外部”数组,事实上,Python 不知道在语法级别涉及任何数组
0赞 chrslg 6/27/2023
Numpy只是一个库。它无法更改语言 (python)。你要求的是语言的改变。这将是一个通用的 python 东西,它允许赋值的右手用一个简单的符号引用“setindex”操作的数组。
0赞 AKX 6/27/2023
如果你真的需要,你可以这样做,但这可能更难阅读。other_precice_array = (lambda s: s[(s > num) | (s.isodd())])(precicely_named_array)

答:

2赞 Michael Cao 6/27/2023 #1

在Python 3.8+中,使用带有 walrus 运算符的临时变量名称。:=

other_precice_array = (_ := precicely_named_array)[(_ > num) | _.isodd()]

评论

0赞 chrslg 6/27/2023
_=precisely_named_array ; other_precise_array=_[(_>num) | _.isodd()]
0赞 chrslg 6/27/2023
换句话说,如果你发现大变量名称太复杂,只需使用更简单的变量名称(至少作为别名,同时保留旧的大名称)。
0赞 Bob 6/27/2023
或保持原答案的精神other_precice_array = (_ := precicely_named_array)[(_ > num) | (_.isodd())]
0赞 tdelaney 6/27/2023 #2

Python 不会自动保留对表达式中值的命名引用 - 并且很难以合理的方式做这样的事情。

您可以使用简洁的名称将计算放入函数中

def large_and_odd(arr, n):
    return arr[(arr > n) | (arr.isodd())])
    
other_precice_array = large_and_odd(precicely_defined_array, num)

这可以在现有函数中完成,也可以在模块级别完成。使用函数来清晰是公平的游戏。你也可以用 lambda 来做,但对于未来的读者来说,它是如何工作的以及你为什么要这样做会令人费解。但。。。

other_precice_array = (lambda arr, n: arr[(arr > n) | (arr.isodd())])\
    (precicely_defined_array, num)

评论

0赞 Michael Sweet 7/12/2023
我认为在某些情况下这可能是正确的解决方案,但至少根据我的经验,索引表达式往往是一次性的(仅在其特定上下文中有用),并且我认为制作函数的可读性比使用 walrus 运算符内联要差一些......不过,这是一个很好的答案。