np.delete和np.s_.np_s有什么特别之处?

Gre*_*ldi 8 indexing numpy slice delete-row python-2.7

我真的不明白为什么常规索引不能用于np.delete.是什么让np.s_如此特别?

例如,使用此代码,用于删除此数组的某些行.

inlet_names = np.delete(inlet_names, np.s_[1:9], axis = 0)
Run Code Online (Sandbox Code Playgroud)

为什么我不能简单地使用常规索引并做..

inlet_names = np.delete(inlet_names, [1:9], axis = 0)
Run Code Online (Sandbox Code Playgroud)

要么

inlet_names = np.delete(inlet_names, inlet_names[1:9], axis = 0)
Run Code Online (Sandbox Code Playgroud)

从我可以收集的内容来看,np.s_与np.index_exp相同,除了它不返回元组,但两者都可以在Python代码中的任何地方使用.

然后,当我查看np.delete函数时,它表明您可以使用类似的东西[1,2,3]删除整个数组中的那些特定索引.那么什么阻止我使用类似的东西删除数组中的某些行或列?

我只是假设这种类型的索引在np.delete中被读取为其他东西所以你需要使用np.s_来指定,但我无法深入了解它究竟是什么读取它因为当我尝试第二段代码时,它只返回"无效语法".这很奇怪,因为这段代码有效......

inlet_names = np.delete(inlet_names, [1,2,3,4,5,6,7,8,9], axis = 0)   
Run Code Online (Sandbox Code Playgroud)

所以我想答案可能是np.delete只接受你想要删除的索引列表.并且np._s返回您为切片指定的索引列表.

只是可以对我刚才所说的关于可能错误的函数的任何内容进行一些澄清和一些修正,因为很多这只是我的看法,文档并没有完全解释我试图理解的所有内容.我想我只是在思考这个问题,但我想真正理解它,如果有人能解释的话.

hpa*_*ulj 15

np.delete没有做任何独特或特殊的事情.它只返回原始数组的副本,但缺少一些项目.大多数代码只是解释输入以准备制作此副本.

你问的是obj参数

obj:slice,int或int数组

简单来说,np.s_您可以使用熟悉的:语法提供切片.该x:y表示法不能用作函数参数.

让我们尝试你的替代方案(你在结果和错误中提到这些,但它们埋在文本中):

In [213]: x=np.arange(10)*2   # some distinctive values

In [214]: np.delete(x, np.s_[3:6])
Out[214]: array([ 0,  2,  4, 12, 14, 16, 18])
Run Code Online (Sandbox Code Playgroud)

因此delete,s_删除一系列值,即6 8 10第3到第5个值.

In [215]: np.delete(x, [3:6])
  File "<ipython-input-215-0a5bf5cc05ba>", line 1
    np.delete(x, [3:6])
                   ^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)

为什么错误?因为[3:4]是索引表达式. np.delete是一个功能.甚至s_[[3:4]]有问题. np.delete(x, 3:6)也很糟糕,因为Python只接受:索引上下文中的语法,它会自动将其转换为slice对象.注意,这是一个syntax error解释器在进行任何计算或函数调用之前捕获的东西.

In [216]: np.delete(x, slice(3,6))
Out[216]: array([ 0,  2,  4, 12, 14, 16, 18])
Run Code Online (Sandbox Code Playgroud)

A slice代替s_; 事实上,这是s_产生的

In [233]: np.delete(x, [3,4,5])
Out[233]: array([ 0,  2,  4, 12, 14, 16, 18])
Run Code Online (Sandbox Code Playgroud)

列表也有效,但它的工作方式不同(见下文).

In [217]: np.delete(x, x[3:6])
Out[217]: array([ 0,  2,  4,  6,  8, 10, 14, 18])
Run Code Online (Sandbox Code Playgroud)

这有效,但产生的结果不同,因为x[3:6]不一样range(3,6).这np.delete也不像list删除.它按索引删除,而不是通过匹配值删除.

np.index_exp失败的原因与此相同np.delete(x, (slice(3,6),)). 1,[1],(1,)都是有效的,并删除一个项目.甚至'1',字符串,工作. delete解析此参数,并在此级别,期望可以转换为整数的东西. obj.astype(intp). (slice(None),)不是一个切片,它是一个1项元组.所以它在delete代码中的不同位置处理.这是TypeError由一种delete叫做非常不同的东西产生的SyntaxError.理论上delete可以从元组中提取切片并按照s_案例进行处理,但开发人员并没有选择考虑这种变化.

对代码的快速研究表明,它np.delete使用了2种不同的复制方法 - 通过切片和布尔掩码.如果obj是一个切片,就像在我们的例子中那样(对于1d数组):

out = np.empty(7)
out[0:3] = x[0:3]
out[3:7] = x[6:10]
Run Code Online (Sandbox Code Playgroud)

但是[3,4,5](而不是切片)它确实:

keep = np.ones((10,), dtype=bool)
keep[[3,4,5]] = False
return x[keep]
Run Code Online (Sandbox Code Playgroud)

结果相同,但采用不同的施工方法. x[np.array([1,1,1,0,0,0,1,1,1,1],bool)]做同样的事情.

事实上,像这样的布尔索引或屏蔽比np.delete通常更强大,并且通常同样强大.


lib/index_tricks.py源文件:

index_exp = IndexExpression(maketuple=True)
s_ = IndexExpression(maketuple=False)
Run Code Online (Sandbox Code Playgroud)

它们是同一件事的略有不同的版本.两者都只是便利功能.

In [196]: np.s_[1:4]
Out[196]: slice(1, 4, None)
In [197]: np.index_exp[1:4]
Out[197]: (slice(1, 4, None),)
In [198]: np.s_[1:4, 5:10]
Out[198]: (slice(1, 4, None), slice(5, 10, None))
In [199]: np.index_exp[1:4, 5:10]
Out[199]: (slice(1, 4, None), slice(5, 10, None))
Run Code Online (Sandbox Code Playgroud)

maketuple仅当存在单个项目,切片或索引时,业务才适用.