Pandas入门

q###### 安装

# 安装pands(默认源)(国内阿里云源)
pip install pands
pip install pandas -i https://mirrors.aliyun.com/pypi/simple/ --trusted-
# 查看版本
pandas.__version__
# 安装pands对excel读依赖库xlrd
pip install xlrd
# 安装pands对excel写依赖库xlwt
pip install xlwt

pandas导入Excel数据

导入Excel
pd.read_excel(‘文件名’)

import pandas as pd
# 解决输出列名不对齐的问题
pd.set_option('display.unicode.east_asian_width', True)
df = pd.read_excel('data.xlsx')
# 显示前五条数据
print(df.head())

解决列名不对齐
pd.set_option(‘display.unicode.east_asian_width’, True)
行列显示不全
(通过修改最大行列数)
pd.set_option(‘display.max_rows’,1000)
pd.set_option(‘display.max_columns’,1000)
显示前n条数据
print(df.head(n))

1.1 Series对象(列)

1.1.1创建Series对象

s = pd.series(data,index=index)

data 表示数据,支持py字典的key、py列表、多维数组、标量值
index 表示行标签(索引),默认为0~len(data)-1,支持py列表

举例

s0 = pd.Series([88,20,60,75])
s1 = pd.Series([88,20,60,75],index=['小刚','小王','小李','小红'])
s2 = pd.Series([88,20,60,75],index=[1,3,4,2])

1.1.2 Series的索引

索引方式

位置索引 s0[0]
标签索引 s1[‘小王’]
多标签索引 s1[[‘小王’,‘小红’]]
切片索引 s1[‘小王’:‘小李’]
位置切片索引(左闭右开) s1[2:3]

获取索引
s1.index
获取Series的值
s1.values

1.2 DateFrame对象(表)

1.2.1 DateFrame对象

pd.DateFrame(data,index,columns,dtype,copy)

data 数据,numpy数组、series对象、列表、字典等
index 行索引
columns 列索引
dtype 每列数据类型
copy 用于复制数据

1.2.2 创建DateFrame对象

通过二位数组创建成绩表

import pandas as pd

pd.set_option('display.unicode.east_asian_width', True)
data = [[110, 105, 99], [105, 88, 115], [109, 120, 130]]
columns = ['语文', '数学', '英语']
df = pd.DataFrame(data=data, columns=columns)
print(df)

通过字典创建成绩表

import pandas as pd

pd.set_option('display.unicode.east_asian_width', True)
df = pd.DataFrame({
    '语文': [110, 105, 99],
    '数学': [105, 88, 115],
    '英语': [109, 120, 130],
    '班级': '高一7班'
}, index=[0, 1, 2])
print(df)
属性 描述 举例
values 查看所有元素的值 df.values
dtypes 查看所有元素的类型 df.dtypes
index 查看所有行名、重命名行名 df.index和df.index = [1,2,3]
columns 查看所有列名、重命名列名 df.columns和df.columns=[‘语’,‘数’,‘外’]
T 行列数据转换 df.T
head 查看前n条数据,默认s条 df.head()和df.head(n)
tail 查看后n条数据,默认5条 df.tail() 和df.tai(n)
shape 查看行数和列数,[0] 表示行;[1]表示列 df.shape[0] df.shape[1]
info 查看索引,数据类型和内存信息 df.info
函数 描述 函数
describe 查看每列的统计汇总信息,DataFame 类型 df.describe0
count 返回每一列中的非 空值的个数 df.count()
sum 返回每一列的和, 无法计算返回空值 df.sum()
max 返回每一列的最大值 df.max()
min 返回每列的最小值 df.min()
argmax 返回最大值所在的自动索引位置 df.argmax()
argmin 返回最小值所在的自动索引位置 df.argmin()
idxmax 返回最大值所在的自定义索引位置 df.idxmax()
idxmin 返回最小值所在的自定义素引位置 df.idxmin()

略后补

1.3 导入外部数据

1.3.1导入xls或xlsx文件

略后补

1.3.1.1常规导入

1.导入1月份的表格文件
import pandas as pd
pd.set_option('display.unicode.east_asian_width', True)
df = pd.read_excel('1月.xlsx')
print(df.head())

补充知识点 相对路径:
…/表示当前文件所在目录的上一级目录
./表示当前文件所在的目录
/表示当前文件的根目录

2. 导入指定sheet页
import pandas as pd
pd.set_option('display.unicode.east_asian_width', True)
# 导入sheet页为莫寒页
df = pd.read_excel('1月.xlsx', sheet_name='莫寒')
# 导入sheet页为第2页
df = pd.read_excel('1月.xlsx', sheet_name=1)
# 导入sheet页为第1、2页和名为sheet的页
df = pd.read_excel('1月.xlsx', sheet_name=[0,1,'sheet'])
print(df.head())
3. 通过行列索引导入指定行列数据

import pandas as pd
pd.set_option('display.unicode.east_asian_width', True)
# 设置第0列为行索引
df = pd.read_excel('1月.xlsx', index_col=0)
print(df.head())

import pandas as pd
pd.set_option('display.unicode.east_asian_width', True)
# 设置第1行为列索引
df = pd.read_excel('1月.xlsx', header=1)
# 将数字设为列索引
df = pd.read_excel('1月.xlsx', header=None)
print(df.head())
4. 导入指定列数据
import pandas as pd
pd.set_option('display.unicode.east_asian_width', True)
# 导入第0列数据
df = pd.read_excel('1月.xlsx', usecols=[0])
# 指定值第0和第3列导入多列数据
df = pd.read_excel('1月.xlsx', usecols=[0,3])
# 指定列名称
df = pd.read_excel('1月.xlsx', usecols=['买家会员名', '宝贝标题'])
print(df.head())

1.3.2 导入.csv文件


csv和py互转需要encoding=gbk

import pandas as pd
# 指定最大列数和宽度
pd.set_option('display.max_columns', 500)
pd.set_option('display.width', 1000)
pd.set_option('display.unicode.east_asian_width', True)
df = pd.read_csv('1月.csv', encoding='gbk')
print(df.head())

1.3.3 导入.txt文件

import pandas as pd

pd.set_option('display.unicode.east_asian_width', True)
df = pd.read_csv('1月.txt', sep='\t', encoding='gbk')
print(df.head())

1.3.4导入.html文件


必须确认网页表格为table标签

import pandas as pd
df = pd.DataFrame()
url_list = ['http://www.espn.com/nba/salaries/_/seasontype/4']
for i in range(2, 13):
    url = 'http://www.espn.com/nba/salaries/_/page/%s/seasontype/4' % i
    print(url)
    url_list.append(url)
#遍历网页中的table读取网页表格数据
for url in url_list:
    df = df.append(pd.read_html(url), ignore_index=True)
#列表解析:遍历dataframe第3列,以子字符串$开头
df = df[[x.startswith('$') for x in df[3]]]
print(df)
df.to_csv('NBA.csv',header=['RK','NAME','TEAM','SALARY'], index=False)

1.2 数据抽取

1.2.1抽取一行数据

import pandas as pd

pd.set_option('display.unicode.east_asian_width', True)
data = [[110, 105, 99], [105, 88, 115], [109, 120, 130], [112, 115]]
name = ['明日', '七月流火', '高圆圆', '二月二']
columns = ['语文', '数学', '英语']
df = pd.DataFrame(data=data, index=name, columns=columns)
print(df.loc['明日'])

1.2.2 抽取多行数据

# 从明日到二月二
print(df.loc['明日':'二月二'])
# 从第0个到七月流火 步进为1 
print(df.loc[:'七月流火':])
# 从第0个到第四个 步进为1 
print(df.iloc[0:4])
# 从第1个到最后一个 步进为1 
print(df.iloc[1::])

1.2.3 抽取指定列数据

可以直接使用列名,也可以使用loc iloc
使用列名

import pandas as pd

pd.set_option('display.unicode.east_asian_width', True)
data = [[110, 105, 99], [105, 88, 115], [109, 120, 130], [112, 115]]
name = ['明日', '七月流火', '高圆圆', '二月二']
columns = ['语文', '数学', '英语']
df = pd.DataFrame(data=data, index=name, columns=columns)
print(df[['语文', '数学']])

loc和iloc属性

# 抽取语文和数学
print(df.loc[:, ['语文', '数学']])
# 抽取第一列和第二列
print(df.iloc[:, [0, 1]])
# 抽取从语文到最后一列
print(df.loc[:, '语文':])
# 连续抽取从第1列开始到第3列,但不包括第二列
print(df.iloc[:, :3])

1.2.4 抽取指定行列数据

import pandas as pd

pd.set_option('display.unicode.east_asian_width', True)
data = [[110, 105, 99], [105, 88, 115], [109, 120, 130], [112, 115]]
name = ['明日', '七月流火', '高圆圆', '二月二']
columns = ['语文', '数学', '英语']
df = pd.DataFrame(data=data, index=name, columns=columns)

# 七月流火的英语成绩 输出为纯成绩
print(df.loc['七月流火', '英语'])
# 七月流火的英语成绩 输出为七月流火的英语成绩dataframe
print(df.loc[['七月流火'], ['英语']])
# 七月流火的英语成绩 输出为七月流火的英语和数学成绩dataframe
print(df.loc[['七月流火'], ['数学', '英语']])
# 第二行第三列 
print(df.iloc[[1], [2]])
# 第二行到最后1行组成的序列的第2列
print(df.iloc[1:, [2]])
# 第二行到最后1行组成的新序列的第1列和第3列
print(df.iloc[1:, [0, 2]])
# 所有行的第三列
print(df.iloc[:, 2])

1.2.5 按指定条件抽取数据

import pandas as pd

pd.set_option('display.unicode.east_asian_width', True)
data = [[110, 105, 99], [105, 88, 115], [109, 120, 130], [112, 115]]
name = ['明日', '七月流火', '高圆圆', '二月二']
columns = ['语文', '数学', '英语']
df = pd.DataFrame(data=data, index=name, columns=columns)



print(df.loc[(df['语文']>105) & (df['数学'] >88)])

1.2.6 数据的增删改

1.2.6.1 增

1. 按列增加数据

三种方法
1.直接为DatafFame对象赋值

import pandas as pd

pd.set_option('display.unicode.east_asian_width', True)
data = [[110, 105, 99], [105, 88, 115], [109, 120, 130], [112, 115]]
name = ['明日', '七月流火', '高圆圆', '二月二']
columns = ['语文', '数学', '英语']
df = pd.DataFrame(data=data, index=name, columns=columns)


df['物理'] = [88, 79, 60, 50]
print(df)

2.使用Loc属性在DataFrame属性增加一列’物理’成绩

df.loc[:, '物理'] = [88, 79, 60, 50]
print(df)

3.在第一列后面插入物理成绩

wl = [88, 79, 60, 50]
df.insert(1, '物理', wl)
print(df)
2. 按行增加数据

两种方法
loc实现增加一行

df.loc['钱多多'] = [100,  120,  99]

增加多行

df_insert = pd.DataFrame({'语文': [100, 123, 138], '数学': [99, 142, 60], '英语': [98, 139, 99]}, index=['钱多多', '童年', '无名'])
df1 = df.append(df_insert)
print(df)

1.2.6.2 改

1. 修改列名
A 修改单个列名

修改数学为数学上

df.columns = ['语文', '数学下', '英语']
print(df)
B 修改多个列名

三个全部修改

df.rename(columns={'语文': '语文上', '数学': '数学上', '英语': '英语上'}, inplace=True)
print(df)
修改行名
将行标统一修改成数字编号
df.index = list('1234')
修改个别行标
df.rename({'明日': 1, '七月流火': 2}, axis=0, inplace=True)
print(df)

修改数据主要使用DataFrame对象中的loc和iloc属性

修改数据

主要使用DataFrame的loc和iloc属性

使用loc属性修改数据

修改整行数据
修改明日同学的三科成绩

df.loc['明日'] = [121, 111, 110]

三科成绩统一变化

df.loc['明日'] = df.loc['明日']+100

修改整列数据

df.loc[:,'语文']=[115,108,112,118]

修改某一处数据
修改明日同学的的语文成绩

df.loc[‘明日’,‘语文’] = 115
使用iloc属性修改数据

通过iloc属性指定行列位置修改数据

#修改某一处数据
df.iloc[0,0]=115
# 修改第三列数据
df.iloc[:, 2] = [1, 8, 112, 118]

# 修改整行第1行数据
df.iloc[0, :] = [1, 8, 112, 118]

删除行列数据
删除列

删除某列

# 搜索数学列 删除数学列
df.drop(['数学'], axis=1, inplace=True)
# 删除column为数学的列
df.drop(columns='数学', inplace=True)
# 删除列标签为数字的列
df.drop(labels='数学', axis=1, inplace=True)
删除行
# 指定删除某几行
df.drop(['明日','二月二'],inplace=True)
# 删除index为'明日'的行
df.drop(index='明日', inplace=True)
# 删除行标签为明日的行
df.drop(labels='明日',axis=0,inspace=True)

DataFram类型index行 column列

删除符合条件的行列综合数据

先找到满足该条件的行索引,再drop

# 删除第一个“数学”包含88的行
df.drop(index=df[df['数学'].isin([88])].index[0],inplace=True)
# 删除第一个语文”小于110的行
df.drop(index=df[df['语文']<110].index[0],inplace=True)

1.3 数据清洗

1.3.1 查看缺省值

查看数据概况

info()方法查看数据概况

import pandas as pd

pd.set_option('display.unicode.east_asian_width', True)
df = pd.read_excel('TB2018.xls')
print(df)
print(df.info())

判断缺省值的两个方法

print(df.isnull()) //缺True 不缺False
print(df.notnull()) //不缺True 缺False
# 查找非缺省数据
print(df[df.isnull() == False])

删除含有缺省值的行

有时候数据可能整行为空 ,可以加速参数how=‘all’

dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)

axis:轴。0或’index’,表示按行删除;1或’columns’,表示按列删除。

how:筛选方式。‘any’,表示该行/列只要有一个以上的空值,就删除该行/列;‘all’,表示该行/列全部都为空值,就删除该行/列。

thresh:非空元素最低数量。int型,默认为None。如果该行/列中,非空元素数量小于这个值,就删除该行/列。

subset:子集。列表,元素为行或者列的索引。如果axis=0或者‘index’,subset中元素为列的索引;如果axis=1或者‘column’,subset中元素为行的索引。由subset限制的子区域,是判断是否删除该行/列的条件判断区域。

inplace:是否原地替换。布尔值,默认为False。如果为True,则在原DataFrame上进行操作,返回值为None。

删除缺省但保留有缺省不影响分析的行

df1 = df[df['宝贝总数量'].notnull()]

缺省值的填充处理

pad/fill函数表示用前一个非缺省值去填充
backfill、bfill表示用下一个非缺省值填充该缺省值
None用于指定一个值去替换该缺省值

对某列标签的缺省值填充为指定值0

df['宝贝总数量'] = df['宝贝总数量'].fillna(0)

重复值处理

判断每一行是否重复

# 返回F不重复 T重复
df.duplicated()

去除全部的重复数据

df.drop_duplicates()

去除指定列的重复数据

df.drop_duplicates([''买家会员名])

保留重复行的最后一行

ad.drop_duplicates(['买家会员名'], keep='last')

直接删除,保留一个副本

df.drop_dumplicates(['买家会员名',‘买家支付宝账号’],inplace = False)

subset: 列名,可选,默认为None

keep: {‘first’, ‘last’, False}, 默认值 ‘first’

first: 保留第一次出现的重复行,删除后面的重复行。
last: 删除重复项,除了最后一次出现。
False: 删除所有重复项。
inplace:布尔值,默认为False,是否直接在原数据上删除重复项或删除重复项后返回副本。(inplace=True表示直接在原来的DataFrame上删除重复项,而默认值False表示生成一个副本。)

异常值的检测预处理

三种:
删除
将异常值当缺失值处理,以某个值填充
将异常值当特殊情况进行分析,研究异常值出现的原因

索引设置

索引的作用

更方便的查询数据
使用索引可以提升查询性能

  • 如果索引是唯一(唯一包含了有序)的,Pandas会使用哈希表优化,查找数据的时间复杂度是o(1)
  • 如果索引不唯一但是有序,Pandas会使用二分法查找算法,查找数据的时间复杂度是LogN
  • 如果索引是完全随机的,那么每次查询都要扫描表,查找数据的时间复杂度是O(n)

重新设置索引

reindex创建一个适应新索引的对象

DataFrame.reindex(labeis=None, index=None,axis=None,method=None,copyu=True,lecel=None,fill_value=nan,limit=None,tolerance=None )
labels 标签,可以是数组,默认为None
index 行索引 ,默认值为None
columns 列索引,
axis 轴, 0表示行,1表示列,默认值为None
method 默认值为None,重新设置索引时,选择差值(用来填充缺失数据的方法,其值可以是None\bfill/backfill(向后填充)、ffill/pad(向前填充)等
fill_value 缺失值要填充的数据,如缺失值不用Nan填充,用0填充,则设置fill_value=0

对Series对象重新设置索引

import pandas as pd

s1 = pd.Series([88, 60, 75], index=[1, 2, 3])
print(s1)
print(s1.reindex([1, 2, 3, 4, 5]))

指定默认的缺失值 fill_value

print(s1.reindex([1, 2, 3, 4, 5], fill_value=2))

向前和向后填充数据 method

# 选择空值前的最后一个(向前填充)
print(s1.reindex([1, 2, 3, 4, 5],  method='ffill'))
# 选择空值后的第一个(向后填充)
print(s1.reindex([1, 2, 3, 4, 5],  method='bfill'))

对DataFrame对象重新设置索引

# 生成一个DF对象
import pandas as pd

pd.set_option('display.unicode.east_asian_width', True)
data = [[110, 105, 99], [105, 88, 115], [109, 120, 130]]
index = ['mr001', 'mr003', 'mr005']
columns = ['语文', '数学', '英语']
df = pd.DataFrame(data=data, index=index, columns=columns)
print(df)

通过reindex方法重新设置行索引

df1 = df.reindex(['mr001', 'mr002', 'mr003', 'mr004', 'mr005'])
print(df1)

通过reindex方法重新设置列索引

df2 = df.reindex(columns=['语文', '物理', '数学', '英语'])
print(df2)

通过reindex方法重新设置行索引列索引

df3 = df.reindex(index=['mr001', 'mr002', 'mr003', 'mr004', 'mr005'], columns=['语文', '物理', '数学', '英语'])
print(df3)

设置某列为索引

主要使用set_index方法
设置买家会员名为行索引

import pandas as pd

pd.set_option('display.unicode.east_asian_width', True)
df = pd.read_excel('1月.xlsx')
print(df.head())

df1 = df.set_index(['买家会员名'])
print(df1)

如果在方法中传入drop=True,则会删除‘买家会员名’;传入drop=False则会保留,默认为False

数据清洗后重新设置连续的行索引

df.dropna().reset_index(drop=True)

数据排序与排名

数据排序

DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind=‘quicksort’, na_position=‘last’, ignore_index=False)

by 要排序的名称列表
axis 轴, 0表示行,1表示列,默认值为None
ascending True升序或者False降序,布尔值,指定多个排序可以使用布尔值列表
inplace 布尔值 默认为False 如果为True则就地排序
kind 指定排序算法,值为默认quicksort快速排序、mergesort混合排序、heapsort堆排
na_position 空值nan的位置,值为first空值在数据开头,值为last空值在数据最后,默认为last
ignore_index 布尔值,是否忽略索引,值为True标记索引(从0开始按顺序的整数值)值为false则忽略索引

按一列数据排序

按销量进行排序降序

import pandas as pd

excelFile = 'mrbook.xlsx'
df = pd.DataFrame(pd.read_excel(excelFile))

# 设置数据显示的列数与宽度
pd.set_option('display.max_columns', 500)
pd.set_option('display.width', 1000)
# 解决数据输出列名不对齐的问题
pd.set_option('display.unicode.ambiguous_as_wide', True)
pd.set_option('display.unicode.east_asian_width', True)
df = df.sort_values(by='销量', ascending=False)
print(df)

按多列数据排序

先按图书名称降序排序,然后再按销量降序排序

df.sort_values(by=['图书名称', '销量'])

对统计结果排序

对分组统计数据进行排序
按类别分组统计销量并进行降序排序

df1 = df.groupby(['类别'])['销量'].sum().reset_index()
df2 = df1.sort_values(by='销量', ascending=False)

按行数据排序

按行数据类型必须要一致
dfrow.sort_values(by=0, ascend=True, axis=1)

数据排名

排名是根据对象的某几列的值进行排名
DataFrame.rank(axis=0, method=‘average’, numeric_only=None, na_option=‘keep’,ascending=True, pct=False)
知乎讲的比较好的

axis
axis 轴, 0表示行,1表示列,默认值为None
method 表示具有相同值的情况下所使用的排序方法
method average 默认值,平均值排名,销量相同
method min 最小值排名
method max 最大值排名
method first 按值在原始数据出现的顺序分配排名
method dense 密集排名,类似最小值排名,但是排名每次增加1,即排名相同的数据只占一个空间,俗称并列

顺序排名

对销量相同的产品,按照出现的先后顺序进行排名

import pandas as pd

excelFile = 'mrbook.xlsx'
df = pd.DataFrame(pd.read_excel(excelFile))

# 设置数据显示的列数与宽度
pd.set_option('display.max_columns', 500)
pd.set_option('display.width', 1000)
# 解决数据输出列名不对齐的问题
pd.set_option('display.unicode.ambiguous_as_wide', True)
pd.set_option('display.unicode.east_asian_width', True)
df = df.sort_values(by='销量', ascending=False)
print(df)
df['顺序排名'] = df['销量'].rank(method='first', ascending=False)
print(df[['图书名称', '销量', '顺序排名']])

平均排名

对销量相同的产品,按照顺序排名的平均值进行排名
并列的排名分是前一名+0.5

df['平均排名'] = df['销量'].rank(ascending=False)
print(df[['图书名称', '销量', '平均排名']])

最小值排名

销量相同的,按顺序排名并取最小值作为排名 前一名+1

df['最小值排名'] = df['销量'].rank(method='min', ascending=False)

最大值排名

销量相同的,按顺序排名并取最大值作为排名 前一名+2

df['最大值排名'] = df['销量'].rank(method='max', ascending=False)
print(df[['图书名称', '销量', '最大值排名']])

你可能感兴趣的:(数据分析,python)