上次我们谈到了一些基本的数据选择方法,既有对列的选择,也有对行的选择。在实际的操作中有时我们经常需要更换显示的内容,今天我来完成这些练习。
比如我们再次看看这个学生数据:
print(frame)
我们首先来看列名称的显示问题。
比如这个列的名称,通常为了方便,列名称都采用英文字母或者一些易于表示的表达方式,但是在实际显示中,考虑到用户的需求,往往需要更改为特定的语种或者格式。比如我们能否把这里的列名称换成中文呢?
当然这种替换有两种方法:
第一是真的替换,这个其实不建议做,列名称通常作为基础性的字段名称,可能使用在很多其他地方,随意更换会导致其他使用旧列名称的地方出问题,带来潜在的错误。
更换方法很简单,可以直接设置DataFrame类变量的columns属性,所谓属性就是指属性值,通常这些数值代表着一种特征,比如columns属性就表示列名称这个特征。
frame.columns = [‘学号’, ‘姓名’, ‘性别’, ‘年龄’, ‘身高’]
后面这个方括号括起来的就是一些数值集合。大家可能也感觉到了,在Python中,如果需要表达多个数值,通常都是这样形成一个组合,这个被称为列表。
第二种是表面的临时性替换,这样显然更灵活。方法也很简单:
print(frame.rename(columns={‘ID’: ‘学号’, ‘name’: ‘姓名’, ‘gender’: ‘性别’}))
这里的rename就是DataFrame类变量的函数方法,大家应该记得上一次我们谈到了loc定位函数。它们都是DataFrame类变量的函数方法,功能不一样。这里的rename就是更换列名称。但是细心的同学可能会发现有点不一样,loc参数是直接写出数值的,但是这里的rename却要说明这些数值是columns列的数值。
这是两种不同的参数使用方法,如果不说明参数的名称,那么你必须严格按照函数方法的要求,按序给出每个参数对应的数值,如果说明参数的名称,并使用等于号赋值,你就可以随意的给出哪个参数对应哪个数值。通常参数少的时候,不说明参数更方便,参数多的时候,说明下更方便。这一点大家有兴趣可以了解下Python更多的基础知识。
看的出来,由于只对前面三个列改了名称,因此后面两列依然还是原有的列名。
这里可以根据需要有选择的更换,这是完整替换的方法:
frame.rename(columns={‘ID’: ‘学号’, ‘name’: ‘姓名’, ‘gender’: ‘性别’, ‘age’: ‘年龄’, ‘height’: ‘身高’})
大家可能也感觉到了,这种以花括号括起来的集合,通常里面都有很多由冒号组成的数值对,这种结构在Python中被称为字典。第一节课里我们定义DataFrame时其实就是采用了字典和列表的组合。
我们再看看数据内容的显示问题。
在实际问题中,存储的数据内容往往都需要做进一步的处理才能更好的显示。比如我们假设要分开显示每个学生的姓和名,我们也假设学生姓都是一个字。
print(frame[‘name’].str[0:1])
这里str也是个函数方法,它是字符串变量的内含函数方法,其实每个name列的数值都是一个字符串,因此都支持字符串自己的操作。这里str表示取子字符串,0到1,不含1,因此就是第一个字符,就是单字的姓。
通过字符串相加表示连接可以形成更多的显示效果。
print(frame[‘name’].str[0:1] + ‘同学’)
也可以形成计算列,并存储下来
frame[‘newname’] = frame[‘name’].str[0:1] + ‘同学’
print(frame)
不同类型的列可以调用自己不同类型的方法,如显示每个学生身高,但是四舍五入到小数1位:
print(frame[‘height’].round(1))
其中round函数的1表示小数1位,如果是0表示四舍五入到个位,-1表示四舍五入到十位,以此类推。
比较复杂的还可以通过自定义函数来扩展功能,实现对更多数据的自定义处理。这个供有Python基础的同学了解。比如下面我们定义了根据增加输出男女的函数,并应用于性别列,产生了更为灵活的效果:
# coding:utf-8
import pandas as pd
from pandas import DataFrame
def xinbie(val):
if val is True:
return '男'
else:
return '女'
data = {'ID': ['000001', '000002', '000003', '000004', '000005', '000006', '000007'],
'name': ['黎明', '赵怡春', '张富平', '白丽', '牛玉德', '姚华', '李南'],
'gender': [True, False, True, False, True, False, True],
'age': [16, 20, 18, 18, 17, 18, 16],
'height': [1.88, 1.78, 1.81, 1.86, 1.74, 1.75, 1.76]
}
frame = pd.DataFrame(data)
print(frame['gender'].apply(xinbie))
定义的xinbie函数接收一个参数,并判断是否为真,如果为真返回一个男,否则为女,看得出来,通过这个函数,原有的性别增加值被映射为男女汉字,解决了输出显示问题。其中,这里因为这个xinbie为自定义函数,不属于frame内置的函数,因此可以通过apply函数来调用其他函数,可以理解为通过apply函数可以调用任何其他函数。
事实上,即使是刚才的一些内置函数,也可以使用apply,比如这里也是四舍五入,通过apply调用round,不过默认round自动四舍五入到个位。
print(frame[‘height’].apply(round))
为了传递给round参数,可以使用apply的args参数,将1,这个表示1个小数位的1,传递给round,大家可以看到结果和刚才直接调用round的做法一样。
print(frame[‘height’].apply(round, args=[1]))
这个apply函数应用的讲解不做要求。
我们再来看看索引号的显示。
默认的索引号也可以更改,比如直接设定index属性即可:
frame.index = [6, 5, 4, 3, 2, 1, 0]
也可以按照前面的rename,指定改变index:
print(frame.rename(index={0: 6, 1: 5, 2: 4, 3: 3, 4: 2, 5: 1, 6: 0}))
注意这里使用了有名参数index,来说明赋值的去向。
注意即使改变后这些索引后,如果通过序号来访问仍然按照从0开始的原始顺序访问,如:
frame = frame.rename(index={0: 6, 1: 5, 2: 4, 3: 3, 4: 2, 5: 1, 6: 0})
print(frame[0:1])
这里我们采取了保存替换原有DataFrame类变量的方法将修改索引确定了下来。此时显示的仍然第一条记录,它显示的新索引号为6。
最后,我们谈谈整体格式化输出的问题,可能大家觉得目前这种文本输出并不好看,甚至连对齐都做不了。不过这个问题其实不大,因为pandas主要特点在于处理数据,它本身并不负责格式输出等其他内容。后续我们可以通过其他可视化工具包来完成真正的格式化。
即使是现在,最为简单的格式化方法可以考虑将数据全部输出为一个网页表格,直接可以看到这个数据表格:
print(frame.to_html())
具体方法是调用DataFrame类变量的to_html函数,它会生成一个网页代码。
大家可以把它复制出来,生成一个网页文件,就能看到真正的表格。
很有帮助!