numpy的花式索引如何实现? [英] How is numpy's fancy indexing implemented?

查看:459
本文介绍了numpy的花式索引如何实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在对2D列表和numpy数组进行一些实验.由此,我提出了3个问题,我很想知道答案.

I was doing a little experimentation with 2D lists and numpy arrays. From this, I've raised 3 questions I'm quite curious to know the answer for.

首先,我初始化了一个2D python列表.

First, I initialized a 2D python list.

>>> my_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

然后我尝试使用元组为列表建立索引.

I then tried indexing the list with a tuple.

>>> my_list[:,]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list indices must be integers, not tuple

由于解释器向我抛出了TypeError而不是SyntaxError,因此我推测实际上可以这样做,但是python本身不支持它.

Since the interpreter throws me a TypeError and not a SyntaxError, I surmised it is actually possible to do this, but python does not natively support it.

然后我尝试将列表转换为numpy数组并执行相同的操作.

I then tried converting the list to a numpy array and doing the same thing.

>>> np.array(my_list)[:,]
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

当然没问题.我的理解是__xx__()方法之一已被覆盖并在numpy程序包中实现.

Of course, no problem. My understanding is that one of the __xx__() methods have been overridden and implemented in the numpy package.

Numpy的索引也支持列表:

Numpy's indexing supports lists too:

>>> np.array(my_list)[:,[0, 1]]
array([[1, 2],
       [4, 5],
       [7, 8]])

这引起了两个问题:

  1. 哪个__xx__方法已覆盖/定义了numpy来处理精美索引?
  2. 为什么python列表本身不支持花式索引编制?
  1. Which __xx__ method has numpy overridden/defined to handle fancy indexing?
  2. Why don't python lists natively support fancy indexing?

(奖金问题:为什么我的时间显示python2中的切片比python3慢?)

(Bonus question: why do my timings show that slicing in python2 is slower than python3?)

推荐答案

您有三个问题:

使用__getitem____setitem____delitem__可以覆盖索引运算符[].编写一个具有自省功能的简单子类可能会很有趣:

The indexing operator [] is overridable using __getitem__, __setitem__, and __delitem__. It can be fun to write a simple subclass that offers some introspection:

>>> class VerboseList(list):
...     def __getitem__(self, key):
...         print(key)
...         return super().__getitem__(key)
...

让我们先做一个空的:

>>> l = VerboseList()

现在用一些值填充它.请注意,我们尚未覆盖__setitem__,因此尚未发生任何有趣的事情:

Now fill it with some values. Note that we haven't overridden __setitem__ so nothing interesting happens yet:

>>> l[:] = range(10)

现在让我们得到一个物品.在索引0处将是0:

Now let's get an item. At index 0 will be 0:

>>> l[0]
0
0

如果我们尝试使用元组,则会出现错误,但是我们首先要查看元组!

If we try to use a tuple, we get an error, but we get to see the tuple first!

>>> l[0, 4]
(0, 4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __getitem__
TypeError: list indices must be integers or slices, not tuple

我们还可以找出python在内部如何表示切片:

We can also find out how python represents slices internally:

>>> l[1:3]
slice(1, 3, None)
[1, 2]

您可以使用此对象做更多有趣的事情-试试看!

There are lots more fun things you can do with this object -- give it a try!

这很难回答.考虑它的一种方式是历史性的:因为numpy开发人员首先想到了它.

This is hard to answer. One way of thinking about it is historical: because the numpy developers thought of it first.

在1991年首次公开发布时,Python没有numpy库,要创建多维列表,您必须嵌套列表结构.我认为早期的开发人员,尤其是Guido van Rossum( GvR )–感到最初,保持简单是最好的.切片索引已经非常强大.

Upon its first public release in 1991, Python had no numpy library, and to make a multi-dimensional list, you had to nest list structures. I assume that the early developers -- in particular, Guido van Rossum (GvR) -- felt that keeping things simple was best, initially. Slice indexing was already pretty powerful.

然而,不久之后,人们开始将Python用作科学计算语言.在1995年至1997年之间,许多开发人员在名为numeric的库中进行了合作,该库是numpy的早期版本.尽管他不是numericnumpy的主要贡献者,但GvR与numeric开发人员进行了协调,以使多维数组索引更容易的方式扩展了Python的slice语法.后来,出现了numeric的替代名称,称为numarray.并在2006年创建了numpy,结合了两者的最佳功能.

However, not too long after, interest grew in using Python as a scientific computing language. Between 1995 and 1997, a number of developers collaborated on a library called numeric, an early predecessor of numpy. Though he wasn't a major contributor to numeric or numpy, GvR coordinated with the numeric developers, extending Python's slice syntax in ways that made multidimensional array indexing easier. Later, an alternative to numeric arose called numarray; and in 2006, numpy was created, incorporating the best features of both.

这些库功能强大,但是需要大量的c扩展,依此类推.将它们工作到基本的Python发行版中将使其变得庞大.尽管GvR确实确实增强了切片语法,但在普通列表中添加花式索引将极大地改变其API,并且在某种程度上是多余的.鉴于已经可以使用外部库进行华丽的索引编制,因此这样做的好处是不值得的.

These libraries were powerful, but they required heavy c extensions and so on. Working them into the base Python distribution would have made it bulky. And although GvR did enhance slice syntax a bit, adding fancy indexing to ordinary lists would have changed their API dramatically -- and somewhat redundantly. Given that fancy indexing could be had with an outside library already, the benefit wasn't worth the cost.

说实话,部分叙述是推测性的. 1 我真的不了解开发人员!但这是我会做出的相同决定.实际上...

Parts of this narrative are speculative, in all honesty.1 I don't know the developers really! But it's the same decision I would have made. In fact...

尽管花式索引功能非常强大,但我很高兴即使在今天它也不是香草Python的一部分,因为这意味着您在使用普通列表时不必费力思考.对于许多任务,您不需要它,并且它施加的认知负担也很大.

Although fancy indexing is very powerful, I'm glad it's not part of vanilla Python even today, because it means that you don't have to think very hard when working with ordinary lists. For many tasks you don't need it, and the cognitive load it imposes is significant.

请记住,我在说的是 readers maintainers 上的负载.您可能是个天才般的天才,可以在您的脑海中制作5维张量积,但其他人则必须阅读您的代码.在numpy中保留花式索引意味着人们不会使用它,除非他们诚实地需要它,这通常会使代码更具可读性和可维护性.

Keep in mind that I'm talking about the load imposed on readers and maintainers. You may be a whiz-bang genius who can do 5-d tensor products in your head, but other people have to read your code. Keeping fancy indexing in numpy means people don't use it unless they honestly need it, which makes code more readable and maintainable in general.

可能.绝对是环境相关的;我在机器上看不到相同的差异.

Possibly. It's definitely environment-dependent; I don't see the same difference on my machine.

1.叙述中不具有推测性的部分来自简史在《科学与工程计算》(2011年第13卷)的一期特刊中讲述.

1. The parts of the narrative that aren't as speculative are drawn from a brief history told in a special issue of Computing in Science and Engineering (2011 vol. 13).

这篇关于numpy的花式索引如何实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆