当前位置:   article > 正文

Python 数据处理工具 Pandas(上)

Python 数据处理工具 Pandas(上)

一、序列与数据框的构造

Pandas模块的核心操作对象就是序列(series)和数据框(DataFrame)。序列可以理解为数据集中的一个字段,数据库是指含有至少两个字段(或序列)的数据集。

1.1构造序列

构造序列的方式:

  • 通过同质的列表或元组构建
  • 通过字典构建
  • 通过Numpy中的一维数组构建
  • 通过数据框DataFrame中的某一列构建
  1. #导入模块
  2. import pandas as pd
  3. import numpy as np
  4. #构造序列
  5. gdp1=pd.Series([2.8,3.01,8.99,8.59,5.18])
  6. gdp2=pd.Series({'北京':2.8,'上海':3.01,'江苏':8.59})
  7. gdp3 = pd.Series(np.array((2.8,3.01,8.99,8.59,5.18)))
  8. print(gdp1)
  9. print(gdp2)
  10. print(gdp3)
  11. out:
  12. 0 2.80
  13. 1 3.01
  14. 2 8.99
  15. 3 8.59
  16. 4 5.18
  17. dtype: float64
  18. 北京 2.80
  19. 上海 3.01
  20. 江苏 8.59
  21. dtype: float64
  22. 0 2.80
  23. 1 3.01
  24. 2 8.99
  25. 3 8.59
  26. 4 5.18
  27. dtype: float64

        Series构造的序列结果会产生两列,第一列属于序列的行索引(可以理解为行号),自动从0开始,第二例是序列的实际的值。通过字典构造,第一列是行名称,对应字典的键,第二列是序列的实际值,对应字典的值。

        序列与一维数组有极高相似性,获取一维数组的索引方法可以应用在序列上,而且数组的数学和统计函数也可以用在序列对象上,不过序列有更多的其他处理方法

  1. # 数学函数--取对数
  2. print('通过numpy函数:\n',np.log(gdp1))
  3. # 平均gdp
  4. print('通过numpy函数:\n',np.mean(gdp1))
  5. print('通过序列的方法:\n',gdp1.mean())
  6. out:
  7. 通过numpy函数:
  8. 0 1.029619
  9. 1 1.101940
  10. 2 2.196113
  11. 3 2.150599
  12. 4 1.644805
  13. dtype: float64
  14. 通过numpy函数:
  15. 5.714
  16. 通过序列的方法:
  17. 5.714

1.2构造数据框

数据框实质就是一个数据集,数据集的行代表每一条观测,数据集的列代表各个变量。在一个数据框中可以存放不同数据类型的序列,如整数型、浮点型、字符型和日期时间型,而数组和序列没有这样的优势,因为他们只能存放同质数据。构造一个数据库应用如下方式:

  • 通过嵌套的列表或元组构造
  • 通过字典构造
  • 通过二维数组构造
  • 通过外部数据的读取构造
  1. # 构造数据框
  2. df1 = pd.DataFrame([['张三',23,'男'],['李四',27,'女'],['王二',26,'女']])
  3. df2 = pd.DataFrame({'姓名':['张三','李四','王二'],'年龄':[23,27,26],'性别':['男','女','女']})
  4. df3 = pd.DataFrame(np.array([['张三',23,'男'],['李四',27,'女'],['王二',26,'女']]))
  5. print('嵌套列表构造数据框:\n',df1)
  6. print('字典构造数据框:\n',df2)
  7. print('二维数组构造数据框:\n',df3)
  8. out:
  9. 嵌套列表构造数据框:
  10. 0 1 2
  11. 0 张三 23
  12. 1 李四 27
  13. 2 王二 26
  14. 字典构造数据框:
  15. 姓名 年龄 性别
  16. 0 张三 23
  17. 1 李四 27
  18. 2 王二 26
  19. 二维数组构造数据框:
  20. 0 1 2
  21. 0 张三 23
  22. 1 李四 27
  23. 2 王二 26

        构造数据框需要使用pandas模块中的DataFrame。将嵌套列表、元组或二维数组转换为数据框是,数据框无具体变量名,只有从0到n的列号。所以,如果需要手工构造数据框时,一般首选字典方法。

二、外部数据的读取

2.1文本文件的读取

        如果读取txt或csv格式的数据,可以使用pandas模块中的read_table函数或者read_csv函数。这两个函数均可以读取文本文件的数据。

pd.read_table(filepath_or_buffer,sep='t',header='infer',names=None,index_col=None,usecols=None,dtype=None,converters=None,skiprows=None,skipfooter=None,nrows=None,na_values=None,skip_blank_lines=True,parse_dates=False,thousands=None,comment=None,encoding=None)

filepath_or_buffer,指定文件路径;

sep,分隔符、默认Tab制表符

header,是否第一行做表头,默认是;

names,原数据集中无字段,可以通过该参数在数据读取时给数据框添加具体的表头;

index_col,指定原数据集中的某些列作为数据框的行索引(标签);

usecols,指定需要读取数据集中的哪些变量名;

dtype,读取数据时,可以为原数据集的每个字段设置不同的数据类型

converters,通过字典格式,为数据集中的某些字段设置转换函数

skiprows,数据读取时,指定需要跳过原数据集开头的行数

skipfooter,数据读取时,指定需要跳过原数据集末尾的行数

nrows,指定读取数据的行数

na_values,指定哪些特征的值为缺失值

skip_blank_lines=True,读取数据时是否需要跳过原数据集中的空白行,默认True

parse_dates=False,如果参数值为True,则尝试解析数据框的行索引;如果参数值为列表,则分析对应的日期列;如果参数值为嵌套列表,则将某些列合并为日期列;如果参数为字典,则对应列(字典中的值),并生成新的字段名(字典中的键)

thousands=None,指定原始数据集的千分位符;

comment=None,指定注释符,在读取数据时,如果碰到行首指定的注释符,则跳过该行

encoding=None如果文件中含有中文,有时候需要指定字符编码

  1. # 读取文本文件中的数据
  2. user_income = pd.read_table(r'''C:\Users\yu'chuan'zhao\Desktop\pythondatacourse\第5章 Python数据处理工具--Pandas\data_test01.txt''', sep = ',',
  3. parse_dates={'birthday':[0,1,2]},skiprows=2, skipfooter=3,
  4. comment='#', encoding='utf8', thousands='&')
  5. user_income
  6. out:
  7. birthday gender occupation income
  8. 0 1990-03-07 男 销售经理 6000
  9. 1 1989-08-10 女 化妆师 8500
  10. 2 1992-10-07 女 前端设计 6500
  11. 3 1985-06-15 男 数据分析师 18000

2.2电子表格的读取

        运用read_execl函数,读取电子表格数据。

pd.read_excel(io,sheetname=0,header=0,skip_footer=0,index_col=None,names=None,parse_cols=None,parse_dates=False,na_values=None,thousands=None,convert_float=True)

io,电子表格具体路径

sheetname=0,指定需要读取电子表格中的第几个sheet,既可以传递整数

header=0,是否需要将数据集的第一行用做表头,默认为是需要的

skip_footer=0,读取数据时,指定跳过的开始行数

index_col=None,指定哪些列用作数据框的行索引

names=None,如果原数据集中没有字段,可以通过该参数在数据读取时给数据框添加具体的表头

parse_cols=None,指定需要解析的字段

parse_dates=False,如果参数值为True,则尝试解析数据框的行索引;如果参数值为列表,则分析对应的日期列;如果参数值为嵌套列表,则将某些列合并为日期列;如果参数为字典,则对应列(字典中的值),并生成新的字段名(字典中的键

na_values=None,指定原始数据集中的千分位符

thousands=None,指定原始数据集中的千分位符

convert_float=True 默认将所有的数值型字段转换为浮点型字段

converters 通过字典的形式,指定某些列需要转换的形式。

  1. child_cloth = pd.read_excel(io = r'''C:\Users\yu'chuan'zhao\Desktop\pythondatacourse\第5章 Python数据处理工具--Pandas\data_test02.xlsx''', header = None,
  2. names = ['Prod_Id','Prod_Name','Prod_Color','Prod_Price'], converters = {0:str})
  3. child_cloth
  4. out:
  5. Prod_Id Prod_Name Prod_Color Prod_Price
  6. 0 00101 儿童裤 黑色 109
  7. 1 01123 儿童上衣 红色 229
  8. 2 01010 儿童鞋 蓝色 199
  9. 3 00100 儿童内衣 灰色 159

        重点说明converters参数,通过该参数可以指定某些变量需要转换的函数。很显然,原始数据集中的商品ID是字符型的,如果不将该参数设置为{0:str},读入的数据与原始的数据集就不一致了。

三、数据类型转换及描述统计

        在我们读取了数据之后,如何了解数据,比如数据的规模、变量所属的数据类型,一些重要指标等,如何查找

        

  1. #数据读取
  2. sec_cars=pd.read_table(r'''C:\Users\yu'chuan'zhao\Desktop\pythondatacourse\第5章 Python数据处理工具--Pandas\sec_cars.csv''',sep=',')
  3. #预览数据的前五行
  4. sec_cars.head()
  5. out:
  6. Brand Name ... Sec_price New_price
  7. 0 众泰 众泰T600 20161.5T 手动 豪华型 ... 6.8 9.42
  8. 1 众泰 众泰Z700 20161.8T 手动 典雅型 ... 8.8 11.92
  9. 2 众泰 大迈X5 20151.5T 手动 豪华型 ... 5.8 8.56
  10. 3 众泰 众泰T600 20171.5T 手动 精英贺岁版 ... 6.2 8.66
  11. 4 众泰 众泰T600 20161.5T 手动 旗舰型 ... 7.0 11.59

        如果只需要预览数据的几行信息,可以使用head方法和tail方法。数据集前五行head,数据集后五行tail。

如果还想知道数据集中有多少观测和多少变量,以及每个变量都是什么类型,可由如下代码得知:

  1. #查看数据的行列数
  2. print('数据集的行列数: \n',sec_cars.shape)
  3. #查看数据集的每个变量的数据类型
  4. print('各变量的数据类型:\n',sec_cars.dtypes)
  5. out:
  6. 数据集的行列数:
  7. (10984, 7)
  8. 各变量的数据类型:
  9. Brand object
  10. Name object
  11. Boarding_time object
  12. Km(W) float64
  13. Discharge object
  14. Sec_price float64
  15. New_price object
  16. dtype: object

        Boarding_time应该为日期型,新车价格New_price 应该为浮点型,为了后面的数据分析,需要对这两个变量进行类型的转换,具体操作如下:

  1. # 修改二手车上牌时间的数据类型
  2. sec_cars.Boarding_time = pd.to_datetime(sec_cars.Boarding_time, format = '%Y年%m月')
  3. # 修改二手车新车价格的数据类型
  4. sec_cars.New_price = sec_cars.New_price.str[:-1].astype('float')
  5. # 重新查看各变量数据类型
  6. sec_cars.dtypes
  7. out:
  8. Brand object
  9. Name object
  10. Boarding_time datetime64[ns]
  11. Km(W) float64
  12. Discharge object
  13. Sec_price float64
  14. New_price float64
  15. dtype: object

        pandas模块中的to_datetime函数可以通过format参数灵活地将各种格式的字符型日期转换成真正的日期数据;由于二手新车价格含有“万”字,因此不能直接转换数据类型,为达到目的,首先字段转换成字符串,然后切片将“万”字剔除,最后运用astype方法,实现数据类型的转换。

        需要对数据做到心中有数,通过基本的统计量(最小值、均值、中位数、最大值等)描述出数据的特征。数据的描述性分析可以使用describe方法。

  1. #数据的描述性统计
  2. sec_cars.describe()
  3. Out:
  4. Km(W) Sec_price New_price
  5. count 10984.000000 10984.000000 10984.000000
  6. mean 6.266357 25.652192 51.326006
  7. std 3.480678 52.770268 79.682066
  8. min 0.020000 0.650000 2.910000
  9. 25% 4.000000 5.200000 16.050000
  10. 50% 6.000000 10.200000 26.690000
  11. 75% 8.200000 23.800000 52.210000
  12. max 34.600000 808.000000 976.920000

        一次性统计数值型变量的偏度和峰度

  1. # 数据的形状特征
  2. # 挑出所有数值型变量
  3. num_variables = sec_cars.columns[sec_cars.dtypes !='object'][1:]
  4. # 自定义函数,计算偏度和峰度
  5. def skew_kurt(x):
  6. skewness = x.skew()
  7. kurtsis = x.kurt()
  8. # 返回偏度值和峰度值
  9. return pd.Series([skewness,kurtsis], index = ['Skew','Kurt'])
  10. # 运用apply方法
  11. sec_cars[num_variables].apply(func = skew_kurt, axis = 0)
  12. out:
  13. Km(W) Sec_price New_price
  14. Skew 0.829915 6.313738 4.996912
  15. Kurt 2.406258 55.381915 33.519911

        对离散型变量的统计描述仍然可以使用describe方法,所不同的是,需要设置该方法的include参数,具体如下

  1. # 离散型变量的统计描述
  2. sec_cars.describe(include = ['object'])

四个统计值分别是 非缺失观测数、唯一水平数、频次最高的离散值和具体的频次。

四、字符与日期数据的处理

        以下图为例,完成字符串和日期数据的处理

  • 如何更改birthday和tel两个字段的数据类型
  • 如何根据birthday和start_work两个字段新增年龄和工龄两个字段
  • 如何将tel中间四位隐藏起来
  • 如何根据邮箱信息新增邮箱域名字段
  • 如何基于other字段取出每个人员的专业信息
  1. # 数据读入
  2. df = pd.read_excel(r'C:\Users\Administrator\Desktop\data_test03.xlsx')
  3. # 各变量数据类型
  4. print(df.dtypes)
  5. # 将birthday变量转换为日期型
  6. df.birthday = pd.to_datetime(df.birthday, format = '%Y/%m/%d')
  7. # 将手机号转换为字符串
  8. df.tel = df.tel.astype('str')
  9. # 新增年龄和工龄两列
  10. df['age'] = pd.datetime.today().year - df.birthday.dt.year
  11. df['workage'] = pd.datetime.today().year - df.start_work.dt.year
  12. # 将手机号中间四位隐藏起来
  13. df.tel = df.tel.apply(func = lambda x : x.replace(x[3:7], '****'))
  14. # 取出邮箱的域名
  15. df['email_domain'] = df.email.apply(func = lambda x : x.split('@')[1])
  16. # 取出用户的专业信息
  17. df['profession'] = df.other.str.findall('专业:(.*?),')
  18. # 去除birthday、start_work和other变量
  19. df.drop(['birthday','start_work','other'], axis = 1, inplace = True)
  20. df.head()
  21. out:
  22. name gender income tel ... age workage email_domain profession
  23. 0 赵一 男 15000 136****1234 ... 33 10 qq.com [电子商务]
  24. 1 王二 男 12500 135****2234 ... 32 8 163.com [汽修]
  25. 2 张三 女 18500 135****3330 ... 35 13 qq.com [数学]
  26. 3 李四 女 13000 139****3388 ... 31 8 gmail.com [统计学]
  27. 4 刘五 女 8500 178****7890 ... 30 8 qq.com [美术]

        pandas模块中的to_datetime函数将birthday转换为日期型(必须按照原始的birthday格式设置format参数);使用astype方法将tel转换为字符型。

        在使用year方法之前,需要使用dt方法,否则会出错。

常用的日期时间处理‘’方法‘’
方法含义方法含义
year返回年份month返回月份
day返回月份的日hour返回时
minute返回分钟second返回秒
date返回日期time返回时间
dayofyear返回年中第几天weekofyear返回年中第几周
dayofweek返回周几weekday_name返回具体的周几名称
quarter返回第几季度days_in_month返回月中第几天
  1. # 常用日期处理方法
  2. dates = pd.to_datetime(pd.Series(['1989-8-18 13:14:55','1995-2-16']), format = '%Y-%m-%d %H:%M:%S')
  3. print('返回日期值:\n',dates.dt.date)
  4. print('返回季度:\n',dates.dt.quarter)
  5. print('返回几点钟:\n',dates.dt.hour)
  6. print('返回年中的天:\n',dates.dt.dayofyear)
  7. print('返回年中的周:\n',dates.dt.weekofyear)
  8. print('返回星期几的名称:\n',dates.dt.day_name)
  9. print('返回月份的天数:\n',dates.dt.days_in_month)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/731653
推荐阅读
相关标签
  

闽ICP备14008679号