你能告诉我什么时候使用这些矢量化方法和基本的例子吗?
我看到map是一个系列方法,而其余的是DataFrame方法。我对apply和applymap方法感到困惑。为什么我们有两个方法来应用一个函数到一个数据帧?再一次,简单的例子说明用法将是伟大的!
你能告诉我什么时候使用这些矢量化方法和基本的例子吗?
我看到map是一个系列方法,而其余的是DataFrame方法。我对apply和applymap方法感到困惑。为什么我们有两个方法来应用一个函数到一个数据帧?再一次,简单的例子说明用法将是伟大的!
当前回答
比较map, applymap和apply: Context Matters
第一个主要区别:定义
map在Series ONLY上定义 applymap只在DataFrames上定义 apply定义在BOTH上
第二个主要区别:INPUT参数
map接受字典、系列或可调用 Applymap和apply只接受可调用对象
第三个主要区别:行为
map是系列的元素 applymap是DataFrames的elementwise Apply也适用于elementwise,但适用于更复杂的操作和聚合。行为和返回值取决于函数。
第四个主要区别(最重要的一个):用例
map用于将值从一个域映射到另一个域,因此对性能进行了优化(例如,df['A']。Map ({1:'a', 2:'b', 3:'c'})) applymap适用于跨多行/列的elementwise转换(例如df[['A', 'B', 'C']]].applymap(str.strip)) Apply用于应用任何不能向量化的函数(例如df['sentence ']. Apply (nltk.sent_tokenize))。
另见什么时候我应该(不)想要在我的代码中使用熊猫apply() ?我写了一篇关于使用apply最合适的场景的文章(注意不是很多,但是有一些——apply通常很慢)。
总结
Footnotes map when passed a dictionary/Series will map elements based on the keys in that dictionary/Series. Missing values will be recorded as NaN in the output. applymap in more recent versions has been optimised for some operations. You will find applymap slightly faster than apply in some cases. My suggestion is to test them both and use whatever works better. map is optimised for elementwise mappings and transformation. Operations that involve dictionaries or Series will enable pandas to use faster code paths for better performance. Series.apply returns a scalar for aggregating operations, Series otherwise. Similarly for DataFrame.apply. Note that apply also has fastpaths when called with certain NumPy functions such as mean, sum, etc.
其他回答
原因:
下面的示例显示apply和applymap应用到一个DataFrame。
map函数只能应用在Series上。不能在DataFrame上应用map。
需要记住的是,apply可以做任何applymap可以做的事情,但apply有额外的选项。
X因子选项是:axis和result_type,其中result_type仅在axis=1时有效(对于列)。
df = DataFrame(1, columns=list('abc'),
index=list('1234'))
print(df)
f = lambda x: np.log(x)
print(df.applymap(f)) # apply to the whole dataframe
print(np.log(df)) # applied to the whole dataframe
print(df.applymap(np.sum)) # reducing can be applied for rows only
# apply can take different options (vs. applymap cannot)
print(df.apply(f)) # same as applymap
print(df.apply(sum, axis=1)) # reducing example
print(df.apply(np.log, axis=1)) # cannot reduce
print(df.apply(lambda x: [1, 2, 3], axis=1, result_type='expand')) # expand result
作为旁注,不应将Series映射函数与Python映射函数混淆。
第一个应用在Series上,用于映射值,第二个应用到可迭代对象的每个项。
最后,不要混淆dataframe apply方法和groupby apply方法。
apply工作在数据帧的行/列基础上 applymap在DataFrame上按元素工作 map在Series上按元素工作
直接摘自Wes McKinney的Python for Data Analysis一书,第132页(我强烈推荐这本书):
另一个常见操作是将一维数组上的函数应用到每一列或行。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
许多最常见的数组统计(如sum和mean)是DataFrame方法, 所以没有必要使用apply。
也可以使用元素级Python函数。假设您希望从帧中的每个浮点值计算一个格式化字符串。你可以用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
命名为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
基于cs95的答案
map在Series ONLY上定义 applymap只在DataFrames上定义 apply定义在BOTH上
举几个例子
In [3]: frame = pd.DataFrame(np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])
In [4]: frame
Out[4]:
b d e
Utah 0.129885 -0.475957 -0.207679
Ohio -2.978331 -1.015918 0.784675
Texas -0.256689 -0.226366 2.262588
Oregon 2.605526 1.139105 -0.927518
In [5]: myformat=lambda x: f'{x:.2f}'
In [6]: frame.d.map(myformat)
Out[6]:
Utah -0.48
Ohio -1.02
Texas -0.23
Oregon 1.14
Name: d, dtype: object
In [7]: frame.d.apply(myformat)
Out[7]:
Utah -0.48
Ohio -1.02
Texas -0.23
Oregon 1.14
Name: d, dtype: object
In [8]: frame.applymap(myformat)
Out[8]:
b d e
Utah 0.13 -0.48 -0.21
Ohio -2.98 -1.02 0.78
Texas -0.26 -0.23 2.26
Oregon 2.61 1.14 -0.93
In [9]: frame.apply(lambda x: x.apply(myformat))
Out[9]:
b d e
Utah 0.13 -0.48 -0.21
Ohio -2.98 -1.02 0.78
Texas -0.26 -0.23 2.26
Oregon 2.61 1.14 -0.93
In [10]: myfunc=lambda x: x**2
In [11]: frame.applymap(myfunc)
Out[11]:
b d e
Utah 0.016870 0.226535 0.043131
Ohio 8.870453 1.032089 0.615714
Texas 0.065889 0.051242 5.119305
Oregon 6.788766 1.297560 0.860289
In [12]: frame.apply(myfunc)
Out[12]:
b d e
Utah 0.016870 0.226535 0.043131
Ohio 8.870453 1.032089 0.615714
Texas 0.065889 0.051242 5.119305
Oregon 6.788766 1.297560 0.860289
@jeremiahbuddha提到apply适用于行/列,而applymap适用于元素。但似乎仍然可以使用apply进行元素计算....
frame.apply(np.sqrt)
Out[102]:
b d e
Utah NaN 1.435159 NaN
Ohio 1.098164 0.510594 0.729748
Texas NaN 0.456436 0.697337
Oregon 0.359079 NaN NaN
frame.applymap(np.sqrt)
Out[103]:
b d e
Utah NaN 1.435159 NaN
Ohio 1.098164 0.510594 0.729748
Texas NaN 0.456436 0.697337
Oregon 0.359079 NaN NaN
除了其他答案,在一个系列中还有map和apply。
Apply可以从一个系列中生成一个DataFrame;然而,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)
Map不仅可以使用函数,还可以使用字典或其他系列。假设你想操纵排列。
Take
1 2 3 4 5
2 1 4 5 3
这个排列的平方是
1 2 3 4 5
1 2 5 3 4
你可以用map来计算。不确定self-application是否有文档记录,但它在0.15.1中可以工作。
In [39]: p=pd.Series([1,0,3,4,2])
In [40]: p.map(p)
Out[40]:
0 0
1 1
2 4
3 2
4 3
dtype: int64