Pandas

  • Python在数据处理和准备⽅⾯⼀直做得很好,但在数据分析和建模⽅⾯就差⼀些。pandas帮助填补了这⼀空⽩,使您能够在Python中执⾏整个数据分析⼯作流程,⽽不必切换到更特定于领域的语⾔,如R。
  • 与出⾊的 jupyter⼯具包和其他库相结合,Python中⽤于进⾏数据分析的环境在性能、⽣产率和协作能⼒⽅⾯都是卓越的。
  • pandas是 Python 的核⼼数据分析⽀持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据。pandas是Python进⾏数据分析的必备⾼级⼯具。
  • pandas的主要数据结构是 Series(⼀维数据)与 DataFrame (⼆维数据),这两种数据结构⾜以处理⾦融、统计、社会科学、⼯程等领域⾥的⼤多数案例
  • 处理数据⼀般分为⼏个阶段:数据整理与清洗、数据分析与建模、数据可视化与制表,Pandas 是处理数据的理想⼯具。
  • pandas官方文档
  • pandas中文文档

安装

pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple

Series

  • Pandas Series 类似表格中的一个列(column),类似于一维数组,可以保存任何数据类型

创建序列

  • pandas.Series(data, index, dtype, name) : 创建一组二维数据

参数描述

  • data : 一组数据(ndarray、list、tuple)
  • index : 数据索引标签,如果不指定,默认从 0 开始
  • dtype : 数据类型,默认会自己判断
  • name : 设置名称
import pandas as pd
import numpy as np

#list 
s =pd.Series([1,2,3,4],index=list("abcd"),name="列表")
print(s)
#tuple
s =pd.Series((3,4,5))
print(s)
#ndarray
s = pd.Series(np.arange(6),index=list("ndarry"),dtype=float)
print(s)

输出结果

a    1
b    2
c    3
d    4
Name: 列表, dtype: int64

0    3
1    4
2    5
dtype: int64

n    0.0
d    1.0
a    2.0
r    3.0
r    4.0
y    5.0
dtype: float64

序列属性

  • obj.dtype : 数据类型
  • obj.ndim : 给定对象的维度
  • obj.size : 长度
  • obj.empty : 如果系列为空,则返回True
  • obj.values : 将序列的数据作为ndarray返回
  • obj.index : 将序列的索引作为ndarray返回
s1 = pd.Series(None)
print(s1.empty)
print(s1.values)
print(s1.index)
print(s1.size)
print(s1.ndim)

输出结果

True
[]
Index([], dtype='object')
0
1

序列的访问与修改

  • 切片使用与列表、数组等一致
  • 利用index标签 和下标均可以访问
  • 利用index值进行切片,闭区间即包含结束的index
s = pd.Series([99,88,77,66],index=["a","b","c","d"],name="ndarray")
print(s["a":"b"])
print(s[0:2])
s["a"] =70
s["b":"d"] =99
print(s)

输出结果

a    99
b    88
Name: ndarray, dtype: int64
a    99
b    88
Name: ndarray, dtype: int64
a    70
b    99
c    99
d    99
Name: ndarray, dtype: int64

序列常用函数

算数函数与Numpy 一致,能用序列对象调用就用序列对象调用,不能就用numpy库调用

  1. a,c 的平均成绩
  2. b,d 的最大成绩
  3. 取前2个人的成绩
import pandas as pd
import numpy as np
s = pd.Series([99,88,77,66],index=["a","b","c","d"],name="ndarray")
print(s[["a","c"]].mean())  # np.mean(s[["a","c"]])
print(s[["b","d"]].max())
print(s["a":"b"])
print(s[s>80])
print(s[[True,True,False,False]])

输出结果

88.0
88
a    99
b    88
Name: ndarray, dtype: int64

字符串函数

Series.str下有相应的字符串函数 也可以利用numpy 的字符串函数处理(记得要转换类型dtype=str)

s = pd.Series(["lili","lingling"," tom","jim ","lucy"," simon "])
print(np.char.capitalize(np.array(s,dtype =str))) # 首字母大写
print(s.str.capitalize())# 首字母大写
print(np.char.upper(np.asarray(s,dtype=str)))# 字母大写
print(s.str.upper())# 字母大写

s = pd.Series(["lili","lingling"," tom","jim ","lucy"," simon "])
#把元素中的i替换为A
print(np.char.replace(np.asarray(s,dtype=str),"i","A"))
print(s.str.replace("i","A"))
#把元素的首尾空格去掉
print(np.char.strip(np.asarray(s,dtype=str)))
print(s.str.strip())

输出结果

['Lili' 'Lingling' ' tom' 'Jim ' 'Lucy' ' simon ']
0        Lili
1    Lingling
2         tom
3        Jim 
4        Lucy
5      simon 
dtype: object
['LILI' 'LINGLING' ' TOM' 'JIM ' 'LUCY' ' SIMON ']
0        LILI
1    LINGLING
2         TOM
3        JIM 
4        LUCY
5      SIMON 
dtype: object



['lAlA' 'lAnglAng' ' tom' 'jAm ' 'lucy' ' sAmon ']
0        lAlA
1    lAnglAng
2         tom
3        jAm 
4        lucy
5      sAmon 
dtype: object
['lili' 'lingling' 'tom' 'jim' 'lucy' 'simon']
0        lili
1    lingling
2         tom
3         jim
4        lucy
5       simon
dtype: object

统计函数

统计函数与numpy函数一致,能用序列对象调用就用序列对象调用,不能就用numpy库调用

s = pd.Series([99,88,77,66],index=["a","b","c","d"],name="ndarray")
print(s.mean(),s.median(),np.percentile(s,[25,50,75]))
print(s.var(),s.std(),np.ptp(s))
print(s.sum(),s.max(),s.min(),s.argmax(),s.argmin(),s.size)

print(np.where(s>80,80,s))
s[[0,1]] = 80 #非切片时,多个索引值要以一个参数形式输入
s

输出结果

82.5 82.5 [74.25 82.5  90.75]
201.66666666666666 14.200938936093861 33
330 99 66 0 3 4

[80 80 77 66]
a    80
b    80
c    77
d    66
Name: ndarray, dtype: int64

其他函数

  • obj.fillna(value,inplace) : 填充缺失值

参数描述

  • value : 要填充的值
  • inplace : 是否在原数据集上进行修改
s1=pd.Series([np.nan,10,5,np.nan])
print(s1)
s1 = s1.fillna(8)
print(s1)

# np.nan 为float型,要为给某个元素改为缺失,要把元素类型改便为float
s = pd.Series(s1,dtype=float) 
s[1] = np.nan
print(s)
s.fillna(s.mean(),inplace=True)# s = s.fillna(s.mean()) 
print(s)

输出结果

0     NaN
1    10.0
2     5.0
3     NaN
dtype: float64
0     8.0
1    10.0
2     5.0
3     8.0
dtype: float64


a    80.0
b     NaN
c    77.0
d    66.0
Name: ndarray, dtype: float64
a    80.000000
b    74.333333
c    77.000000
d    66.000000
Name: ndarray, dtype: float64

DataFrame

  • 是由多种类型的列构成的⼆维标签数据结构,类似于 Excel,SQL表,或Series对象构成的字典。
  • 是表格型的数据结构,具有行和列
  • 中的每个数据值都可以被修改
  • 结构的行数、列数允许增加或者删除
  • 有两个方向的标签轴,分别是行标签和列标签
  • 可以对行和列执行算术运算

创建数据框

  • pandas.DataFrame( data, index, columns)

参数描述

  • data : 一组数据(ndarray,series,tuple, lists, dict 等类型)
  • index : 索引值,或者可以称为行标签
  • columns : 列标签,默认为 RangeIndex (0, 1, 2, …, n)
import pandas as pd
print(pd.DataFrame((1,2,3),columns=["a"]))
#列表
l1 = [['Google',10],['Runoob',12],['Wiki',13]]
df = pd.DataFrame(l1,columns=['Site','Age'])
print(df)
#字典
dic1  = {'Site':['Google', 'Runoob', 'Wiki'], 'Age':[10, 12, 13]}
df = pd.DataFrame(dic1)
print(df)
#字典
dic2 = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}]
df = pd.DataFrame(dic2)
print(df)
#字典
dic3 = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']),
   'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(dic3)
print(df)

输出结果

   a
0  1
1  2
2  3

     Site  Age
0  Google   10
1  Runoob   12
2    Wiki   13

     Site  Age
0  Google   10
1  Runoob   12
2    Wiki   13

   one  two
a  1.0    1
b  2.0    2
c  3.0    3
d  NaN    4

查看其他属性概览

属性

  • df.shape : 查看形状,⾏数和列数
  • df.dtypes : 查看数据类型
  • df.index : ⾏索引
  • df.columns : 列索引
  • df.values : 对象值,⼆维ndarray数组
  • df.size : DataFrame中的元素数量
  • df.ndim : 轴的数量,也指数组的维数
  • df.empty : DataFrame中没有数据或者任意坐标轴的长度为0,则返回True
  • df.axes : 返回一个仅以行轴标签和列轴标签为成员的列表
  • df.T : 行和列转置

概览

  • df.head(10) : 显示头部10⾏,默认5个
  • df.tail(10) : 显示末尾10⾏,默认5个
  • df.describe() : 查看数值型列的汇总统计,计数、平均值、标准差、最⼩值、四分位数、最⼤值
  • df.info() : 查看列索引、数据类型、⾮空计数和内存信息
import pandas as pd
import numpy as np
data = {'name': ['John', 'Mike', 'Mozla', 'Rose', 'David', 'Marry', 'Wansi', 'Sidy', 'Jack', 'Alic'],
        'age': [20, 32, 29, np.nan, 15, 28, 21, 30, 37, 25],
        'gender': [0, 0, 1, 1, 0, 1, 0, 0, 1, 1],
        'isMarried': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
label = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
data = pd.DataFrame(data,index=label)
print(data.dtypes)
print(data.index)
print(data.columns)
print(data.values) 
print(data.size)
print(data.ndim)
print(data.empty)
print(data.axes)
data.head()
data.tail()
data.describe()
data.info()

输出结果

name          object
age          float64
gender         int64
isMarried     object
dtype: object
Index(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], dtype='object')
Index(['name', 'age', 'gender', 'isMarried'], dtype='object')
[['John' 20.0 0 'yes']
 ['Mike' 32.0 0 'yes']
 ['Mozla' 29.0 1 'no']
 ['Rose' nan 1 'yes']
 ['David' 15.0 0 'no']
 ['Marry' 28.0 1 'no']
 ['Wansi' 21.0 0 'no']
 ['Sidy' 30.0 0 'yes']
 ['Jack' 37.0 1 'no']
 ['Alic' 25.0 1 'no']]
40
2
False
[Index(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], dtype='object'), Index(['name', 'age', 'gender', 'isMarried'], dtype='object')]
<class 'pandas.core.frame.DataFrame'>
Index: 10 entries, a to j
Data columns (total 4 columns):
 #   Column     Non-Null Count  Dtype  
...
 2   gender     10 non-null     int64  
 3   isMarried  10 non-null     object 
dtypes: float64(1), int64(1), object(2)
memory usage: 400.0+ bytes

行/列读取和修改数据

  • df[列标签_可列表包含多列] : 不能切片
  • df.列标签 : 读取整列
  • df[行标签切片] : 是闭区间
  • df[行下标切片] : 是左闭右开
  • df[条件] : 显示符合条件的行
df = pd.DataFrame([[1,2,3],[4,5,6]],columns=["a","b","c"],index=["x","y"])
print(df)
print(df["a"])
print(df.a)
# #使用切片的方式同时选取多行
print(df["x":"y"])
# #行索引选取数据
print(df[:])
print(df[df["a"] > 3])
print(df["a"]>3)

输出结果

   a  b  c
x  1  2  3
y  4  5  6
x    1
y    4
Name: a, dtype: int64
x    1
y    4
Name: a, dtype: int64
   a  b  c
x  1  2  3
y  4  5  6
   a  b  c
x  1  2  3
y  4  5  6
   a  b  c
y  4  5  6
x    False
y     True
Name: a, dtype: bool

loc/iloc 选择

在数据分析过程中,很多时候需要从数据表中提取出相应的数据,而这么做的前提是需要先“索引”出这一部分数据。虽然通过 Python 提供的索引操作符[]和属性操作符.可以访问 Series 或者 DataFrame 中的数据,但这种方式只适应与少量的数据,为了解决这一问题,Pandas 提供了两种类型的索引方式来实现数据的访问

  • df.loc[] : 只能使用标签检索,不能使用下标检索。当通过标签检索的切片方式来筛选数据时,它的取值前闭后闭,也就是只包括边界值标签(开始和结束)

.loc[]具有多种访问方法,如下所示

  • 一个标量标签["a"]df.loc["a","age"]
  • 标签列表[["a","b"]]df.loc[["a","b"],["age","gender"]]
  • 标签切片对象(闭区间)df.loc["a":"b","age":"gender"]
  • 布尔数组条件df.loc[df.gender==0,["name","age"]]
#创建一组数据
data = {'name': ['John', 'Mike', 'Mozla', 'Rose', 'David', 'Marry', 'Wansi', 'Sidy', 'Jack', 'Alic'],
        'age': [20, 32, 29, np.nan, 15, 28, 21, 30, 37, 25],
        'gender': [0, 0, 1, 1, 0, 1, 0, 0, 1, 1],
        'isMarried': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
label = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
df = pd.DataFrame(data, index=label)
print(df)

输出结果

    name    age gender  isMarried
a   John    20.0    0   yes
b   Mike    32.0    0   yes
c   Mozla   29.0    1   no
d   Rose    NaN 1   yes
e   David   15.0    0   no
f   Marry   28.0    1   no
g   Wansi   21.0    0   no
h   Sidy    30.0    0   yes
i   Jack    37.0    1   no
j   Alic    25.0    1   no
  • df.iloc[] : 只能使用下标,不能使用标签索引,通过下标切片选择数据时,前闭后开(不包含边界结束值)。同Python和NumPy一样,它们的索引都是从0开始

.iloc[]提供了以下方式来选择数据

  • 整数索引df.iloc[0,1]
  • 整数列表df.iloc[[0,3],[1,5]]
  • 数值范围(切片)df.iloc[:,:]
data = {'name': ['John', 'Mike', 'Mozla', 'Rose', 'David', 'Marry', 'Wansi', 'Sidy', 'Jack', 'Alic'],
        'age': [20, 32, 29, np.nan, 15, 28, 21, 30, 37, 25],
        'gender': [0, 0, 1, 1, 0, 1, 0, 0, 1, 1],
        'isMarried': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
label = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
df = pd.DataFrame(data, index=label)
print(df)

输出结果

name    age gender  isMarried
a   John    20.0    0   yes
b   Mike    32.0    0   yes
c   Mozla   29.0    1   no
d   Rose    NaN 1   yes
e   David   15.0    0   no
f   Marry   28.0    1   no
g   Wansi   21.0    0   no
h   Sidy    30.0    0   yes
i   Jack    37.0    1   no
j   Alic    25.0    1   no

演示

#创建一组数据
data = {'name': ['John', 'Mike', 'Mozla', 'Rose', 'David', 'Marry', 'Wansi', 'Sidy', 'Jack', 'Alic'],
        'age': [20, 32, 29, np.nan, 15, 28, 21, 30, 37, 25],
        'gender': [0, 0, 1, 1, 0, 1, 0, 0, 1, 1],
        'isMarried': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
label = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
df = pd.DataFrame(data, index=label)

1.名字长度为4的gender 
2.提取行标签为e,f,g 的三行数据
3.年龄大于30的数据 

#1
df.gender[df.name.str.len()==4]
df.loc[df.name.str.len()==4,"gender"]
#2
df.loc["e":"g",:]
#3
df.loc[df.age>30,:]

1. 奇数行的age,gender列 (按计数算奇数)
2. 前3行的偶数列(按计数算偶数)
3. 把age的缺失值赋值为25 
4. 名字以M开头的所有数据
5. 名字包含a(不分大小写)的数据
6. age>20 并且 gender 为 0 的数据

#1
df.iloc[::2,[1,2]]
#2
df.iloc[:3,1::2]
#3
#df["列名"].isnull() 或 df["列名"].isna()
df.loc[df.age.isnull(),"age"] = 25
#4
df.loc[df.name.str.startswith("M"),:] 
#5
df.loc[df.name.str.lower().str.contains("a"),:]
#6
df.loc[ (df.age>20) & (df.gender==0) ,:]
#注意: 多条件时,一定把每个条件都括上

添加删除

添加

  1. 行添加df1.append(df2)同列表的append
  2. 列添加df1["新列名"] = 常数或数据组,当为原有列名时变为修改
  3. 列添加_指定位置添加df.insert(位置_列下标,"新列名",常数或数据)

删除

  1. 列删除del df["列名"]
  2. 列删除df.pop("列名")
  3. 列删除df.drop("列名",axis=1)
  4. 行删除df.drop("行标签",axis=0)
data = {'name': ['John', 'Mike', 'Mozla', 'Rose', 'David', 'Marry', 'Wansi', 'Sidy', 'Jack', 'Alic'],
        'age': [20, 32, 29, np.nan, 15, 28, 21, 30, 37, 25],
        'gender': [0, 0, 1, 1, 0, 1, 0, 0, 1, 1],
        'isMarried': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
label = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
df = pd.DataFrame(data, index=label)

#  删除age列
del df["age"]
#df.pop("age")
#df.drop("age",axis=1)
#删除a,c 行 
df.drop(["a","c"])
#添加 学历列
df["edu"] ="本科"
#添加  m行
df_test  = df["a":"a"]
df_test.index = ["m"]
df_test.name = "gu"
df_test
df.append(df_test)
# m = pd.DataFrame([["Nancy",35,0,"yes"]],index =["m"] ,columns=df.columns)
# df.append(m)
#添加数据行 (以列标签进行对应)

输出结果

    name    gender  isMarried   edu
a   gu  0   yes 本科
b   Mike    0   yes 本科
c   Mozla   1   no  本科
d   Rose    1   yes 本科
e   David   0   no  本科
f   Marry   1   no  本科
g   Wansi   0   no  本科
h   Sidy    0   yes 本科
i   Jack    1   no  本科
j   Alic    1   no  本科
m   gu  0   yes 本科

数据集成

#指定位置插入行
import numpy as np
import pandas as pd
df1 = pd.DataFrame(data = np.random.randint(0,151,size = (10,3)),
index = list('ABCDEFGHIJ'),
columns = ['Python','Keras','Tensorflow'])
df1.insert(loc = 1,column='Pytorch',value=1024) # 插⼊列
df1
# 对⾏的操作,使⽤追加append,默认在最后⾯,⽆法指定位置
# 如果想要在指定位置插⼊⾏:切割-添加-合并

concat数据串联

  1. append添加列结构一致的数据df1.append(df2)
  2. concat,axis=0以列标签对应添加,axis=1以行标签对应添加pd.concat([df1,df2],axis=0),pd.concat([df1,df3],axis=1)
import pandas as pd
import numpy as np
df1 = pd.DataFrame(data = np.random.randint(0,150,size = [10,3]),# 计算机科⽬的考试成绩
index = list('ABCDEFGHIJ'),# ⾏标签,⽤户
columns=['Python','Tensorflow','Keras']) # 考试科⽬
df2 = pd.DataFrame(data = np.random.randint(0,150,size = [10,3]),# 计算机科⽬的考试成绩
index = list('KLMNOPQRST'),# ⾏标签,⽤户
columns=['Python','Tensorflow','Keras']) # 考试科⽬
df3 = pd.DataFrame(data = np.random.randint(0,150,size = (10,2)),index = list('ABCDEFGHIJ'),columns=['PyTorch','Paddle'])

pd.concat([df1,df2],axis = 0) # df1和df2⾏串联,df2的⾏追加df1⾏后⾯
df1.append(df2) # 在df1后⾯追加df2
pd.concat([df1,df3],axis = 1) # df1和df2列串联,df2的列追加到df1列后⾯

统计指标

import pandas as pd
import numpy as np

data = pd.read_json('../data_test/ratings.json')

# print(data)
fracture = data.loc['Fracture']

#均值
# print(np.mean(fracture))
# print(data.mean(axis=1))


#加权均值
# print(fracture)
weights = [1,10,1,1,1,10,1]
# print(np.average(fracture,weights=weights))
#
# print(fracture)

#最大值索引
# print(np.argmax(fracture))
# print(fracture.idxmax())

#中位数
# print(np.median(fracture))

# 标准差
# print(data.std())
print(fracture.std()) #样本
print(np.std(fracture,ddof=1)) #总体

外部数据获取

df1 = pd.DataFrame(data = np.random.randn(1000,4),
index = pd.date_range(start = '27/6/2010',periods=1000),
columns=list('ABCD'))
#保存csv文件
df1.to_csv("test.csv",index=False)

# 读取csv或文本文件
read_data = pd.read_csv("test.csv")
r = pd.read_table("test.csv",delimiter=",")

r.head()

#读取json数据
data = pd.read_json('../data_test/ratings.json')
# print(data)

#to_json
data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]}
df = pd.DataFrame(data, index=['s1','s2','s3','s4'])
print(df)
print(df.to_json(orient='values'))


#读取mysql 数据
#!pip install pymysql #安装pymysql 
import pymysql #引用pymysql 
con =pymysql.connect(host="127.0.0.1", user="root" ,password="123456",port=3306,db="edu") #链接
df1 = pd.read_sql_query("select * from dw_user",con)
df1.head()

#读取excel 数据
#!pip install xlwt
#!pip install xlrd
df.to_excel("aa.xls",sheet_name="Score",index=False)