Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python/numpy:对切片求反或求补_Python_Arrays_Numpy_Slice - Fatal编程技术网

python/numpy:对切片求反或求补

python/numpy:对切片求反或求补,python,arrays,numpy,slice,Python,Arrays,Numpy,Slice,我有一些函数,是大型分析软件的一部分,它们需要一个布尔掩码来将数组项分成两组。这些功能如下所示: def process(data, a_mask): b_mask = -a_mask res_a = func_a(data[a_mask]) res_b = func_b(data[b_mask]) return res_a, res_b 现在,我需要将这些函数(无需修改)用于一个只包含“a”类项的大数组,但我希望保存RAM,并且不传递带有allTrue的布尔掩

我有一些函数,是大型分析软件的一部分,它们需要一个布尔掩码来将数组项分成两组。这些功能如下所示:

def process(data, a_mask):
    b_mask = -a_mask
    res_a = func_a(data[a_mask])
    res_b = func_b(data[b_mask])
    return res_a, res_b
现在,我需要将这些函数(无需修改)用于一个只包含“a”类项的大数组,但我希望保存RAM,并且不传递带有all
True
的布尔掩码。例如,我可以传递一个切片,如
slice(None,None)

问题是,如果
a\u mask
是片,那么
b\u mask=-a\u mask
行将失败。理想情况下,
-一个_掩码
应该给出一个0项选择

我正在考虑创建一个“修改的”切片对象,该对象将
\uuuu neg\uuuu()方法实现为空切片(例如
slice(0,0)
)。我不知道这是否可能


其他不允许修改
process()
函数,但同时避免分配全真布尔数组的解决方案也将被接受。

不幸的是,我们无法将
\uuu neg\uuu()
方法添加到
切片
。但是,
tuple
可以被子类化,我们可以使用它来保存单个
切片
对象

这让我想到了一个非常非常恶劣的黑客行为,这对你来说应该很有用:

class NegTuple(tuple):
    def __neg__(self):
        return slice(0)
我们可以创建包含单个切片对象的
NegTuple

nt = NegTuple((slice(None),))
这可以用作索引,对其求反将产生一个空切片,从而对0长度的数组进行索引:

a = np.arange(5)
print a[nt]
# [0 1 2 3 4]
print a[-nt]
# []
然而,你必须非常绝望地求助于这样的事情。这样修改
过程是完全不可能的吗

def process(data, a_mask=None):
    if a_mask is None:
        a_mask = slice(None)  # every element
        b_mask = slice(0)     # no elements
    else:
        b_mask = -a_mask
    res_a = func_a(data[a_mask])
    res_b = func_b(data[b_mask])
    return res_a, res_b

这是一种更加明确的方式,对于您当前的用例来说,不应该对其行为产生任何影响。

您的解决方案非常类似于退化稀疏布尔数组,尽管我不知道有任何相同的实现。我下意识的反应是不喜欢,但如果你真的不能修改
过程,这可能是最好的方法。

如果你担心内存使用,那么高级索引可能是个坏主意。从

高级索引始终返回数据的副本(与返回视图的基本切片不同)

目前,
过程
功能具有:

  • 数据
    大小
    n
    say
  • a_掩码
    大小
    n
    (假设采用高级索引)
并创造:

  • b_掩码
    大小
    n
  • 数据[a_mask]
    大小
    m
    say
  • 数据[b_掩码]
    大小
    n-m
这实际上是4个大小为
n
的数组

基本切片似乎是最好的选择,但是Python似乎不允许子类化
slice

TypeError: Error when calling the metaclass bases
    type 'slice' is not an acceptable base type
请参阅@ali_m的答案,了解包含切片的解决方案

或者,您可以绕过
过程
,将结果作为

result = func_a(data), func_b([])

OP正在寻找一个不改变
过程的解决方案
@PeterGibson,而我的判断更好我已经用这样一个解决方案更新了我的答案,这个解决方案真的很可怕,但在提供一个有效的解决方案方面做得很好:)我同意这并不漂亮,但
过程
功能实际上相当复杂,分析的很大一部分取决于它的正确性。我宁愿对这个特定的用例进行黑客攻击,也不愿意冒着弄乱其他(已经过良好测试的)用例的风险。谢谢。随你的便,但如果我是你,我会更担心黑客可能出了什么问题。你的
过程
函数有多复杂其实并不重要——最终,所有的更改都将相当于一个关键字参数和5或6行新行来处理条件。什么是退化的稀疏布尔数组,以及它如何避免创建全真布尔数组?@user2304916稀疏矩阵压缩某些值(通常为0)。布尔稀疏矩阵可以很容易地编写,以压缩构成多数的任何值(真或假)。你的是退化的,因为它只适用于全零或全一的矩阵。是的,一个布尔稀疏矩阵可以压缩真或假。在scipy/numpy IMHO中有这样一个野兽会很好。是的,但是有时候,奇特的索引是唯一的方法(如果目标元素的间距不规则,等等)。不幸的是,我不能在这里使用基本切片,因为这两个组的元素是无序的。感谢您深入了解使用布尔掩码的内存使用情况。@user2304916是的,对于一般用途,我可以看出布尔掩码是必要的。我指的是你问题中的案例,切片是合适的。