新闻资讯

新闻资讯 媒体报道

Pandas中有map,还有applymap和apply方法/函数,它们之间有什么区别?

编辑:016     时间:2022-01-19

简单示例比较

我们知道map是Series方法,另外2个是的是DataFrame方法。容易让人困惑的是apply和applymap方法——为什么我们有两种方法将函数应用于DataFrame?

我们看看来自韦斯·麦金尼(Wes McKinney)的Python for Data Analysis书的解释,第132页。(强烈推荐这本书):

Another frequent operation is applying a function on 1D arrays to each column or row. DataFrame’s apply method does exactly this:

译文:另一常见操作是将一维数组上的函数应用于每一列或每一行。 DataFrame的apply方法正是这样做的:

In [116]: frame = DataFrame(np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])

In [117]: frame
Out[117]: 
               b         d         e
Utah   -0.029638 1.081563 1.280300 Ohio 0.647747 0.831136 -1.549481 Texas 0.513416 -0.884417 0.195343 Oregon -0.485454 -0.477388 -0.309548 In [118]: f = lambda x: x.max() - x.min()

In [119]: frame.apply(f)
Out[119]: 
b 1.133201 d 1.965980 e 2.829781 dtype: float64

Many of the most common array statistics (like sum and mean) are DataFrame methods, so using apply is not necessary.

Element-wise Python functions can be used, too. Suppose you wanted to compute a formatted string from each floating point value in frame. You can do this with applymap:

译文:许多最常见的数组统计信息(例如sum和mean)用DataFrame内置方法就可以实现, 当然也可以使用基于元素的Python函数,所以做这些计算的话apply并不是必须的。假设您要根据DataFrame中的每个浮点值来计算格式化的字符串,您可以使用applymap做到这一点:

In [120]: format = lambda x: '%.2f' % x In [121]: frame.applymap(format)
Out[121]: 
            b      d      e
Utah    -0.03 1.08 1.28 Ohio 0.65 0.83 -1.55 Texas 0.51 -0.88 0.20 Oregon  -0.49 -0.48 -0.31 

The reason for the name applymap is that Series has a map method for applying an element-wise function:

译文:之所以使用applymap作为名称,是因为Series具有用于应用逐元素函数的map方法:

In [122]: frame['e'].map(format) Out[122]: Utah 1.28 Ohio -1.55 Texas 0.20 Oregon -0.31 Name: e, dtype: object 

总结起来,apply在DataFrame的行/列上执行,applymap在DataFrame的元素上执行,map在系列数据(Series)上按元素执行。

全面的差异对比

map,applymap和apply的比较:上下文相关

第一个主要区别:定义

  • map仅在Series(系列)上定义
  • applymap仅在DataFrame上定义
  • apply在Series和DataFrame两者上均有定义

第二个主要区别:输入参数

  • map接受dict,Series或可调用的函数对象
  • applymap和apply仅接受可调用函数对象

第三大区别:行为

  • map是对Series按元素操作的
  • applymap是对DataFrames按元素操作的
  • apply也可以逐元素运行,但适用于更复杂的操作和聚合。行为和返回值取决于函数。

第四大区别(最重要的区别):用例

  • map用于将值从一个域映射到另一个域,因此针对性能进行了优化(例如df['A'].map({1:'a', 2:'b', 3:'c'}))
  • applymap适用于跨多个行/列的元素转换(例如df[['A', 'B', 'C']].applymap(str.strip))
  • apply用于应用无法向量化的任何功能(例如df['sentences'].apply(nltk.sent_tokenize))

小结

Footnotes(脚注)

  1. 传入字典/系列参数时,map将基于该字典/系列中的键来映射元素。缺少的值将在输出中记录为NaN。
  2. 最新版本中的applymap已针对某些操作进行了优化。在某些情况下,您会发现applymap的速度比apply速度稍快。我的建议是对它们都进行测试,并使用更好的方法。
  3. map针对元素映射和转换进行了优化。涉及字典或系列的操作将使Panda是能够使用更快的代码路径来获得更好的性能。
  4. Series.apply返回用于聚合操作的标量,或者返回Series。对于DataFrame.apply来说也一样。请注意,当通过某些NumPy函数(例如均值,总和等)调用apply时,apply也具有快速路径。

补充的知识点

Series.apply和Series.map的功能之间有很多重叠之处,这意味着在大多数情况下任何一种都可以使用。但是,它们确实有一些细微的差异,参考下面的对比示例,map只会将一个系列放在另一个系列的每个单元格中,这可能不是您想要的。

In [40]: p=pd.Series([1,2,3])
In [41]: p Out[31]: 0    1
1    2
2    3 dtype: int64 In [42]: p.apply(lambda x: pd.Series([x, x])) Out[42]:  0  1
0  1  1
1  2  2
2  3  3

In [43]: p.map(lambda x: pd.Series([x, x])) Out[43]:  0    0    1
1    1 dtype: int64 1    0    2
1    2 dtype: int64 2    0    3
1    3 dtype: int64 dtype: object 

另外,如果我有一个带有副作用的函数,例如“连接到Web服务器”,则可能为了清楚起见,我可能会使用apply。

series.apply(download_file_for_every_element)
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

回复列表

相关推荐