看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
pandas 的 map() 是根据输入对应关系映射序列的值。Series 和 DataFrame 的 map() 是通过向参数传递函数来对各元素应用函数的方法。也可以在 map() 的参数中指定词典类型 dict,在该情况下将完成元素的置换。从 pandas 2.1 开始,增加了 DataFrame.map,可以对 DataFrame 中的每个元素进行处理。
它与 apply 的区别如图所示:
pandas.Series.map 将用传递到 map 中的内容替换序列的值,pandas.Series.apply 将对序列的值应用函数(可能带有参数)。区别在于可以传递给方法的内容:
pandas.Series.map
用于用另一个值替换序列中的每个值,该值可以从函数(传入值为 Series 的值)、dict 或 Series 中派生。语法为:
Series.map(arg, na_action=None)
参数:
返回:
当 arg 是字典时,字典中不存在的系列值(作为键)将转换为 NaN。但是,如果 dictionary 是一个 dict 子类,它定义了 __missing__
(即提供了一个默认值的方法),那么使用这个默认值而不是 NaN。
总结一下,arg 可传入的函数形式有以下几种:
ser.map({ 100:'满分', 69: '刚及格'}) # 字典
ser.map(pd.Series(['满分', '刚及格'], index=[100, 60])) # Series
ser.map(fun) # 自定义函数
ser.map(abs) # python 内置函数
ser.map('[{}]'.format) # python 类型方法
ser.map(lambda x: x**2) # lambda
ser.map(np.mean) # numpy 等其他库的函数 ufunc
ser.map(pd.Series.abs) # Pandas 自己的函数
以下是一些案例:
s = pd.Series(['cat', 'dog', np.nan, 'rabbit'])
s
'''
0 cat
1 dog
2 NaN
3 rabbit
dtype: object
'''
map 接受 dict 或 Series。在 dict 中找不到的值将转换为 NaN,除非 dict 具有默认值(例如 defaultdict):
s.map({'cat': 'kitten', 'dog': 'puppy'})
'''
0 kitten
1 puppy
2 NaN
3 NaN
dtype: object
'''
它还接受一个函数:
s.map('I am a {}'.format)
'''
0 I am a cat
1 I am a dog
2 I am a nan
3 I am a rabbit
dtype: object
'''
为避免将函数应用于缺少的值(并保持为 NaN),可以使用 nau_action='ignore':
s.map('I am a {}'.format, na_action='ignore')
'''
0 I am a cat
1 I am a dog
2 NaN
3 I am a rabbit
dtype: object
'''
按元素方式将函数应用于Dataframe。
DataFrame.map(func, na_action=None, **kwargs)
参数和应用逻辑与 Series 的同名方法一样,因此我们就不再使用 applymap 了。
一些例子:
df = pd.DataFrame([[1, 2.12], [3.356, 4.567]])
df
'''
0 1
0 1.000 2.120
1 3.356 4.567
'''
df.map(lambda x: len(str(x)))
'''
0 1
0 3 4
1 5 5
'''
# 与Series.map一样,NA值可以忽略:
df_copy = df.copy()
df_copy.iloc[0, 0] = pd.NA
df_copy.map(lambda x: len(str(x)), na_action='ignore')
'''
0 1
0 NaN 4
1 5.0 5
'''
# 请注意,有些 func 其实有矢量化版本操作,速度会快得多。
# 如,你可以按元素对每个数字进行平方
df.map(lambda x: x**2)
'''
0 1
0 1.000000 4.494400
1 11.262736 20.857489
'''
# 但在这种情况下最好避免使用 map
df ** 2
'''
0 1
0 1.000000 4.494400
1 11.262736 20.857489
'''
pandas.Index.map 使用输入对应关系(dict、Series 或 function)映射值。语法为:
Index.map(mapper, na_action=None)
参数:
返回:
进行要素置换的方法有 replace(),但如果将 pandas.Series 或 pandas.DataFrame 的列(=pandas.Series)的全部元素置换为其他值,则 map() 的情况较多,而且速度也比较快些。
一般情况下,以下两个代码效果一样:
s.map({'NY': 'NewYork', 'CA': 'California', 'TX': 'Texas'})
s.replace({'NY': 'NewYork', 'CA': 'California', 'TX': 'Texas'})
不同的是,map 如果没有对应的映射时会返回 NaN,而 replace 则返回原值。这个问题,可以配合 update() 来解决:
s.update(s.map({'NY': 'NewYork'}))
(针对 pandas 2.1 版本以下)
apply、map、applymap 对数据类型的支持情况如下:
方法 | DataFrame | Series |
---|---|---|
apply | 支持 | 支持 |
map | - | 支持 |
applymap | 支持 | - |
可以看到,map、applymap 仅支持一种数据类型,apply 全支持。相关方法对比示意图如下:
由于 map 在映射时对于映射表中没有的键会返回缺失值 nan,如果想继续保留原来值时,可以用 Series.replace。
可以调用 map()
的对象还有以下对象:
更新时间:2023-09-01 11:11:09 标签:pandas map 映射 函数