【问题标题】:Map vs applymap when passing a dictionary传递字典时映射与应用映射
【发布时间】:2015-05-27 15:51:14
【问题描述】:

我认为我对 map 和 applymap 的理解非常好,但是遇到了问题(如果有兴趣,请参阅 here 了解更多背景信息)。

一个简单的例子:

df  = pd.DataFrame( [[1,2],[1,1]] ) 
dct = { 1:'python', 2:'gator' }

df[0].map( lambda x: x+90 )
df.applymap( lambda x: x+90 )

这按预期工作 - 都在元素基础上运行,在系列上映射,在数据帧上应用映射(解释得很好 here btw)。

如果我使用字典而不是 lambda,map 仍然可以正常工作:

df[0].map( dct )

0    python
1    python

但不是applymap:

df.applymap( dct )
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-100-7872ff604851> in <module>()
----> 1 df.applymap( dct )

C:\Users\johne\AppData\Local\Continuum\Anaconda\lib\site-packages\pandas\core\frame.pyc in applymap(self, func)
   3856                 x = lib.map_infer(_values_from_object(x), f)
   3857             return lib.map_infer(_values_from_object(x), func)
-> 3858         return self.apply(infer)
   3859 
   3860     #----------------------------------------------------------------------

C:\Users\johne\AppData\Local\Continuum\Anaconda\lib\site-packages\pandas\core\frame.pyc in apply(self, func, axis, broadcast, raw, reduce, args, **kwds)
   3687                     if reduce is None:
   3688                         reduce = True
-> 3689                     return self._apply_standard(f, axis, reduce=reduce)
   3690             else:
   3691                 return self._apply_broadcast(f, axis)

C:\Users\johne\AppData\Local\Continuum\Anaconda\lib\site-packages\pandas\core\frame.pyc in _apply_standard(self, func, axis, ignore_failures, reduce)
   3777             try:
   3778                 for i, v in enumerate(series_gen):
-> 3779                     results[i] = func(v)
   3780                     keys.append(v.name)
   3781             except Exception as e:

C:\Users\johne\AppData\Local\Continuum\Anaconda\lib\site-packages\pandas\core\frame.pyc in infer(x)
   3855                 f = com.i8_boxer(x)
   3856                 x = lib.map_infer(_values_from_object(x), f)
-> 3857             return lib.map_infer(_values_from_object(x), func)
   3858         return self.apply(infer)
   3859 

C:\Users\johne\AppData\Local\Continuum\Anaconda\lib\site-packages\pandas\lib.pyd in pandas.lib.map_infer (pandas\lib.c:56990)()

TypeError: ("'dict' object is not callable", u'occurred at index 0')

所以,我的问题是为什么不在这里 map 和 applymap 以类似的方式工作?是applymap的bug,还是我做错了什么?

编辑添加:我发现我可以很容易地解决这个问题:

df.applymap( lambda x: dct[x] )

        0       1
0  python   gator
1  python  python

或者通过这个不需要 lambda 的 answer 更好。

df.applymap( dct.get )

所以这几乎完全一样,对吧?必须与 applymap 解析语法的方式有关,我猜函数/方法的显式形式比字典更有效。无论如何,我想现在这里没有实际问题,但如果有人想回答,我仍然对这里发生的事情感兴趣。

【问题讨论】:

  • df.applymap() 不要在 DataFrame 的每个 Series 上应用 .map(),在每个 Series 上放置 map .apply()。请参阅此处的 Series .apply():link 并且 .apply() 需要一个函数作为参数,并且不能像 .map() 那样使用字典。
  • 对不起,我真的不明白你在说什么。我想 applymap 和 map 是不等价的,我没有异议,但我对为什么或如何没有更好的理解。引用上面的链接(引用一个非常流行的 SO 答案):“applymap 在 DataFrame 上以元素方式工作,而 map 在系列上以元素方式工作。”我希望对这一点进行一些详细说明。

标签: python pandas


【解决方案1】:

.applymap() 和 .map() 确实可以按元素工作。但是 .applymap() 不会对每一列执行 .map() ,而是对每一列执行 .apply() 。

所以当你调用 df.applymap(dct) 时: 发生了什么是 df[0].apply(dct),而不是 df[0].map(dct)

这两个系列方法有什么区别:

.map() 接受 Series、dict 和 function(任何可调用的,因此 dict.get 之类的方法也可以)作为第一个参数;因为 .apply() 只接受函数(或任何可调用的)作为第一个参数。

.map() 包含 if 语句以确定传递的第一个参数是 dict、Series 还是函数,并根据输入正确执行。当您将函数传递给 .map() 时,.map() 方法的作用与 .apply() 相同。

但是 .apply() 没有那些允许它正确处理字典和系列的 if 语句。它只知道如何使用可调用的。

当您使用函数调用 .apply() 或 .map() 时,它们都会调用 lib.map_infer(),它们看起来就像 python 的 map() 函数(但我可以把手放在源代码,所以我不完全确定)。

执行 map(dct, df[0]) 会出现与 df.applymap(dct) 相同的错误,而 df[0].apply(dct) 也会出现相同的错误。

现在,你可以问为什么使用 .apply() 而不是 .map(),如果 .map() 在用函数调用时做同样的事情并且可以使用 dict 和 Series?

因为如果您传递给它的函数的结果是一个系列,.apply() 可以返回一个数据框。

ser = pandas.Series([1,2,3,4,5], index=range(5))

ser_map = ser.map(lambda x : pandas.Series([x]*5, index=range(5)))
type(ser_map)
pandas.core.series.Series

ser_app = ser.apply(lambda x : pandas.Series([x]*5, index=range(5)))
type(ser_app)
pandas.core.frame.DataFrame

【讨论】:

  • 谢谢!显示 map 如何生成系列并应用生成数据框的示例还解释了我过去得到但不理解的一些结果。我对这一切的理解还不到 100%,但这有帮助。
猜你喜欢
  • 1970-01-01
  • 2020-04-15
  • 1970-01-01
  • 2019-01-15
  • 2021-08-02
  • 2011-08-25
  • 2010-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多