【问题标题】:Speed difference between bracket notation and dot notation for accessing columns in pandas括号表示法和点表示法在熊猫中访问列的速度差异
【发布时间】:2019-10-08 00:05:25
【问题描述】:

让我们有一个小数据框:df = pd.DataFrame({'CID': [1,2,3,4,12345, 6]})

当我搜索会员资格时,根据我是要求搜索 df.CID 还是 df['CID'],速度会有很大不同。

In[25]:%timeit 12345 in df.CID
Out[25]:89.8 µs ± 254 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In[26]:%timeit 12345 in df['CID']
Out[26]:42.3 µs ± 334 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In[27]:type( df.CID)
Out[27]: pandas.core.series.Series

In[28]:type( df['CID'])
Out[28]: pandas.core.series.Series

这是为什么呢?

【问题讨论】:

  • 不是一个完整的答案,但是; 总是 引用 pandas 中的列时使用括号索引。点快捷方式有效,但这是不好的做法。一个原因,也可能是它需要更长时间的原因之一,是在 python 中,object.thing 通常用于对象的属性。在这种情况下,数据框具有.shape, .columns, .name 之类的属性(最后一个是另一个很好的理由,使用括号可以有一个名为['name'] 的列),因此尝试将列作为属性而不是显式作为列
  • +/- 边距非常大 - 确定效果是真实的/一般的?
  • 我认为您希望在大多数情况下使用 df['CID'],因为通过 DataFrame 属性访问列存在一些细微差别。我还想补充一点,我认为您想在 df['CID'].values 中搜索 12345,以检查该数字是否在系列中。否则它将检查该数字是否在索引中。

标签: python pandas performance


【解决方案1】:

df['CID'] 委托给NDFrame.__getitem__,更明显的是您正在执行索引操作。

另一方面,df.CID 委托给NDFrame.__getattr__,它必须做一些额外的繁重工作,主要是为了确定“CID”是属性、函数还是使用属性调用的列访问(方便,但不推荐用于生产代码)。


现在,为什么不推荐呢?考虑一下,

df = pd.DataFrame({'A': [1, 2, 3]})
df.A

0    1
1    2
2    3
Name: A, dtype: int64

将“A”列称为df.A 没有问题,因为它与pandas 中的任何属性或函数命名不冲突。但是,请考虑 pop 函数(仅作为示例)。

df.pop
# <bound method NDFrame.pop of ...>

df.popdf 的绑定方法。现在,出于各种原因,我想创建一个名为“pop”的列。

df['pop'] = [4, 5, 6]
df
   A  pop
0  1    4
1  2    5
2  3    6

很好,但是,

df.pop
# <bound method NDFrame.pop of ...>

我无法使用属性表示法访问此列。不过……

df['pop']

0    4
1    5
2    6
Name: pop, dtype: int64

括号符号仍然有效。这就是为什么这更好。

【讨论】:

  • 所以总之不要设置存在于 df 函数空间中的列名。
  • @prosti 不,有时这是无法避免的。这里真正的结论是使用df['col'] 而不是df.col,除非您确定“col”不是属性或函数名。
  • 当我看到人们使用df.col 访问时,我总是试图解释这一点。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多