Why/How Pandas 是否对 .loc 和 .iloc 使用方括号?

Why/How does Pandas use square brackets with .loc and .iloc?

所以 .loc 和 .iloc 不是您的典型函数。他们以某种方式使用 [ 和 ] 包围参数,使其与普通数组索引相当。但是,我从来没有在另一个库中看到过这个(我能想到的,也许 numpy 就像我正在空白的东西),而且我不知道它在技术上如何 works/is 在 [=18] 中定义=]代码。

这种情况下的括号只是函数调用的语法糖吗?如果是这样,那么如何使任意函数使用方括号而不是圆括号呢?不然他们的use/defintionPandas有什么特别的?

在幕后,两者都在使用 __setitem____getitem__ 函数。

注意:此答案的第一部分是 my answer to this other question 的直接改编,在重新打开此问题之前已回答。我在第二部分详细阐述了“为什么”。

So .loc and .iloc are not your typical functions

确实,它们根本不是函数。我将用 loc 举例,iloc 是类似的(它使用不同的内部 classes)。 检查 loc 实际是什么的最简单方法是:

import pandas as pd
df = pd.DataFrame()
print(df.loc.__class__)

打印

<class 'pandas.core.indexing._LocIndexer'>

这告诉我们 df.loc_LocIndexer class 的一个实例。语法 loc[] 源自 _LocIndexer defines __getitem__ and __setitem__* 这一事实,即每当您使用方括号语法时调用的方法 python。

所以是的,从技术上讲,括号是 一些 函数调用的语法糖,只是不是你认为的函数(当然有很多原因 python 是这样设计的,我不会在这里详细介绍,因为 1) 我不够专业,无法提供详尽的答案,以及 2) 关于这个主题,网络上有很多更好的资源)。

*从技术上讲,定义这些方法的是它的基础 class _LocationIndexer,我在这里稍微简化一下


Why does Pandas use square brackets with .loc and .iloc?

我在这里进入猜测区域,因为我在 Pandas 中找不到任何明确讨论设计选择的文档,但是:我认为至少有两个很好的理由选择方括号。

第一个也是最重要的原因是:您根本无法用函数调用来完成您用方括号表示法所做的一切,因为分配给函数调用是 python 中的语法错误:

# contrived example to show this can't work
a = []
def f():
  global a
  return a
f().append(1) # OK
f() = dict() # SyntaxError: cannot assign to function call

使用圆括号进行“函数”调用,调用基础 __call__ 方法(注意任何定义 __call__ 的 class 都是 callable,因此“函数" call 是一个不正确的术语,因为 python 不关心某些东西 一个函数还是只是表现得像一个函数)。

根据调用发生的时间,使用方括号替代地调用 __getitem____setitem____setitem__ 如果它在赋值运算符的左侧,__getitem__ 在任何其他情况下)。无法通过函数调用来模拟这种行为,您需要一个 setter 方法来修改数据框中的数据,但在赋值操作中仍然不允许这样做:

# imaginary method-based alternative to the square bracket notation:
my_data = df.get_loc(my_index)
df.set_loc(my_index, my_data*2)

这个例子让我想到了第二个原因:一致性。您可以通过方括号访问 DataFrame 的元素:

something = df['a']
df['b'] = 2*something

当使用 loc 时,您仍在尝试引用 DataFrame 中的某些项目,因此使用相同的语法而不是要求用户使用某些 getter 和 setter 功能(我相信它也是“更多 pythonic”,但这是一个我宁愿远离的模糊概念)。