为什么/如何使用带有.loc和.iloc的方括号?

时间:2017-09-12 12:40:34

标签: python pandas

所以.loc和.iloc不是你的典型功能。它们以某种方式使用[和]来包围参数,使其与正常的数组索引相当。但是,我从来没有在另一个库中看到过这种情况(我可以想到,也许这就是我正在搞砸的东西),而且我不知道它在技术上如何工作/在python代码中定义。

在这种情况下括号是函数调用的语法糖吗?如果是这样,那么如何使用括号而不是括号来制作任意函数?否则,他们使用/定义熊猫有什么特别之处?

感谢。

2 个答案:

答案 0 :(得分:3)

在封面下方,两者都使用__setitem____getitem__功能。

答案 1 :(得分:2)

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

<块引用>

所以 .loc 和 .iloc 不是你典型的函数

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

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

哪个打印

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

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

所以,是的,从技术上讲,括号是某些函数调用的语法糖,只是不是您认为的函数(当然,python 以这种方式设计的原因有很多,我不会的)此处不详述,因为 1) 我不够专业,无法提供详尽的答案;2) 网络上有很多关于此主题的更好的资源)。

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


<块引用>

为什么 Pandas 在 .loc 和 .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__ 的类都是 callable,因此“函数”调用是一个不正确的术语因为 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”,但这是一个我宁愿远离的模糊概念)。