首页 > pandas 阅读数:18

pandas映射与数据转换

映射就是创建一个映射关系列表,把元素和一个特定的标签或者字符串绑定起来。定义映射关系最好使用字典。例如:

map={'label1':'value1','label2':'value2',…}

在 pandas 中提供了利用映射关系来实现某些操作的函数,具体如下:
  • replace() 函数:替换元素;
  • map() 函数:新建一列;
  • rename() 函数:替换索引。

用映射替换元素

在数据处理时,经常会遇到需要将数据结构中原来的元素根据实际需求替换成新元素的情况。要想用新元素替换原来元素,就需要定义一组映射关系。在映射关系中,将旧元素作为键,新元素作为值。

例如,创建字典 fruits 用于指明水果标识和水果名称的映射关系。

fruits={101:'orange',102:'apple',103:'banana'}


如要将用于存储水果标识、水果数量和单价的 DataFrame 对象中的水果标识替换成水果名称,就需要运用 replace() 函数,通过 fruits 映射关系来实现元素的替换。

replace() 函数的基本语法格式如下。

obj.replace(to_replace=None,value=None,inplace=False,limit=None,regex=
False,method='pad')

函数中的参数说明如下:
  • obj:DataFrame 或 Series 对象;
  • to_replace:接收 str、regex、list、dict、Series、int、float 或者 None,表示将被替换的值;
  • value:接收标量、字典、列表、str、正则表达式,默认为 None;用于替换与 to_replace 匹配的任何值的值;对于 DataFrame,可以使用值的 dict 来指定每列使用哪个值(不在 dict 中的列将不会被填充);还允许使用正则表达式、字符串和列表或这些对象的 dict;
  • inplace:接收布尔值,默认为 False,如果是 True,将修改原来的数据;
  • limit:接收 int,默认为 None,用于限制填充次数;
  • regex:接收 bool 或与 to_replace 相同的类型,默认为 False,表示是否将 to_replace 或 value 解释为正则表达式,如果是 True,那么 to_replace 必须是一个字符串,当是正则表达式或正则表达式的列表、字典或数组时,to_replace 必须为 None;
  • method:取值为 {'pad','ffill','bfill',无},表示替换时使用的方法,与缺失值填充方法类似,当 to_replace 是标量、列表或元组时,值为 None。

【例 1】利用 replace() 函数和映射关系实现将水果数据框中水果标识替换成水果名称。

示例代码 test1.py 如下。
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
#创建水果标识与水果名称的映射关系
fruits = {101:'orange',102:'apple',103:'banana'}
#创建水果数据框DataFrame
data = pd.DataFrame({'fru_No':[101,102,103],'fru_Num':[1000,2000,3000]
                    ,'price':[3.56,4.2,2.5]})
#用映射替换fru_No列的元素
newDf = data.replace(fruits)
print(newDf)

replace() 函数应用的示例代码 example1.py 如下。
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
s = Series([-1000,-999,2,3,4,5,-2000])
#单数值替换
print(s.replace(-2000,np.nan))
#将多个数值替换
print(s.replace([-1000,-999],0))
#不同的值进行不同的替换
print(s.replace([-1000,-999],[np.nan,0]))
#用字典方式进行不同的替换
print(s.replace({-1000:np.nan,-999:0,-2000:np.nan}))

用映射添加元素

在【例 1】中介绍了利用函数和映射来实现将水果标识替换成水果名称的方法。但是有时需要保留水果标识,将水果名称添加到数据集中。那么,这时可利用 map() 函数,通过构建 fruits 映射关系来实现元素的添加。

map() 函数是作用于 Series 或 DataFrame 对象的一列,它接收一个函数或表示映射关系的字典作为参数,它的基本语法格式如下:

Series.map(arg,na_action=None)

函数中的参数说明如下:
  • arg:接收 function、dict 或 Series,表示映射通信;
  • na_action:取值为{无,'忽略'},默认值为 None,如果为'忽略',则传播 NA 值,而不将它们传递给映射对应关系。

【例 2】利用 map() 函数和映射关系实现将水果名称添加到水果数据框中。

示例代码 test2.py 如下。
# -*- coding: utf-8 -*-
import pandas as pd
#创建水果标识与水果名称的映射关系
fruits = {101:'orange',102:'apple',103:'banana'}
#创建水果数据框DataFrame
data = pd.DataFrame({'fru_No':[101,102,103],'fru_Num':[1000,2000,3000],'price'
                    [3.56,4.2,2.5]})
#用映射为data添加fru_name列元素
data['fru_name'] = data['fru_No'].map(fruits)
print(data)

重命名轴索引

在数据处理中,有时需要使用映射关系转换轴标签。pandas 的 rename() 函数是以表示映射关系的字典对象作为参数,替换轴的索引标签。

rename() 函数的基本语法格式如下:

DataFrame.rename(mapper=None,index=None,columns=None,axis=None,copy=True,
inplace=False,level=None)

Series.rename(index=None,**kwargs)

函数中的参数说明如下:
  • mapper、index、columns:接收 dict或 function,表示将 dict 或函数转换为应用于该轴的值,使用 mapper 参数要指定映射器;使用 columns 参数可重命名各列;
  • axis:接收 int 或 str,可选,表示映射器定位的轴,可以是轴名称(“index”,“columns”)或数字(0,1),默认为“index”;
  • copy:接收 boolean,默认为 True,表示是否复制数据;
  • inplace:接收 boolean,默认为 False,如果为 True,将会修改原来的数据;
  • level:接收 int 或 level name,默认为 None,如果是 MultiIndex,只重命名指定级别中的标签。

rename() 函数返回值是 DataFrame 或 Series。

【例 3】利用 rename() 函数和映射关系重命名水果数据框的行索引和列索引。

示例代码 test3.py 如下。
# -*- coding: utf-8 -*-
import pandas as pd

#创建行索引的映射关系
reindex = {0:'row1',1:'row2',2:'row3'}
#创建水果数据框DataFrame
data = pd.DataFrame({'fru_No':[101,102,103],'fru_Num':[1000,2000,3000],'price':
                    [3.56,4.2,2.5]})
#用映射重命名水果数据框的行索引,产生新DataFrame,但原数据不改变
newDf = data.rename(reindex)
print(newDf,'\n',data)
#用映射重命名水果数据框的行索引,产生新DataFrame,但原数据改变
newDf = data.rename(reindex,inplace=True)
print(newDf,'\n',data)

#创建列索引的映射关系
recolumns = {'fru_No':'col1','fru_Num':'col2','price':'col3'}
#用映射重命名水果数据框中的行索引和列索引
newDf = data.rename(index=reindex,columns=recolumns)
print(newDf)
#用映射重命名水果数据框的单个行索引和单个列索引
newDf = data.rename(index={0:'row1'},columns={'fru_No':'col1'})
print(newDf)

注意:rename() 函数返回一个经过改动的新 DataFrame 对象,但原 DataFrame 对象仍保持不变,如果要改变调用函数的对象本身,可使用 inplace 选项,并将其值设置为 True。