Python数据分析处理库——Pandas

原文:https://www.cnblogs.com/nxld/p/6058591.html

目录

数据结构简介:DataFrame 和 Series

1.Series的创建

2.DataFrame的创建

数据索引index

1.通过索引值或索引标签获取数据

2.自动化对齐

利用pandas查询数据

统计分析

pandas实现SQL操作

1.增:添加新行或增加新列

2.删:删除表、观测行或变量列

3.改:修改原始记录的值

4.查:类似上边的数据查询部分

5.聚合:通过groupby()函数实现数据的聚合操作

6.排序

7.多表连接

缺失值处理

实现excel的数据透视表功能

多层索引的使用


  • 数据结构简介:DataFrame 和 Series

pandas中有两类非常重要的数据结构,就是序列Series和数据框DataFrame.

Series类似于NumPy中的一维数组,可以使用一维数组的可用函数和方法,而且还可以通过索引标签的方式获取数据,还具有索引的自动对齐功能。

DataFrame类似于numpy中的二维数组,同样可以使用numpy数组的函数和方法,还具有一些其它灵活的使用。

1.Series的创建

序列的创建主要有三种方式:

(1)通过一维数组创建序列

import pandas as pd
import numpy as np

arr1=np.arange(10)
print("数组arr1:",arr1)
print("arr1的数据类型:",type(arr1))

s1=pd.Series(arr1)
print("序列s1:\n",s1)
print("s1的数据类型:",type(s1))
数组arr1: [0 1 2 3 4 5 6 7 8 9]
arr1的数据类型: <class 'numpy.ndarray'>
序列s1:
 0    0
1    1
2    2
3    3
4    4
5    5
6    6
7    7
8    8
9    9
dtype: int32
s1的数据类型: <class 'pandas.core.series.Series'>

(2)通过字典的方式创建序列

dict1={'a':1,'b':2,'c':3,'d':4,'e':5}
print("字典dict1:",dict1)
print("dict1的数据类型:",type(dict1))

s2=pd.Series(dict1)
print("序列s2:",s2)
print("s2的数据类型:",type(s2))
字典dict1: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
dict1的数据类型: <class 'dict'>
序列s2: a    1
b    2
c    3
d    4
e    5
dtype: int64
s2的数据类型: <class 'pandas.core.series.Series'>

(3)通过DataFrame中的某一行或某一列创建序列

2.DataFrame的创建

数据框的创建主要有三种方式:

(1)通过二维数组创建数据框

print("第一种方法创建DataFrame")
arr2=np.array(np.arange(12)).reshape(4,3)
print("数组2:",arr2)
print("数组2的类型",type(arr2))

df1=pd.DataFrame(arr2)
print("数据框1:\n",df1)
print("数据框1的类型:",type(df1))
第一种方法创建DataFrame
数组2: [[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
数组2的类型 <class 'numpy.ndarray'>
数据框1:
    0   1   2
0  0   1   2
1  3   4   5
2  6   7   8
3  9  10  11
数据框1的类型: <class 'pandas.core.frame.DataFrame'>

(2)通过字典的方式创建数据框

字典列表:

print("第二种方法创建DataFrame")
dict2={'a':[1,2,3,4],'b':[5,6,7,8],'c':[9,10,11,12],'d':[13,14,15,16]}
print("字典2-字典列表:",dict2)
print("字典2的类型",type(dict2))

df2=pd.DataFrame(dict2)
print("数据框2:\n",df2)
print("数据框2的类型:",type(df2))
第二种方法创建DataFrame
字典2-字典列表: {'a': [1, 2, 3, 4], 'b': [5, 6, 7, 8], 'c': [9, 10, 11, 12], 'd': [13, 14, 15, 16]}
字典2的类型 <class 'dict'>
数据框2:
    a  b   c   d
0  1  5   9  13
1  2  6  10  14
2  3  7  11  15
3  4  8  12  16
数据框2的类型: <class 'pandas.core.frame.DataFrame'>

嵌套字典:

dict3={'one':{'a':1,'b':2,'c':3,'d':4},
      'two':{'a':5,'b':6,'c':7,'d':8},
      'three':{'a':9,'b':10,'c':11,'d':12}}
print("字典3-嵌套字典:",dict3)
print("字典3的类型",type(dict3))

df3=pd.DataFrame(dict3)
print("数据框3:\n",df3)
print("数据框3的类型:",type(df3))
字典3-嵌套字典: {'one': {'a': 1, 'b': 2, 'c': 3, 'd': 4}, 'two': {'a': 5, 'b': 6, 'c': 7, 'd': 8}, 'three': {'a': 9, 'b': 10, 'c': 11, 'd': 12}}
字典3的类型 <class 'dict'>
数据框3:
    one  two  three
a    1    5      9
b    2    6     10
c    3    7     11
d    4    8     12
数据框3的类型: <class 'pandas.core.frame.DataFrame'>

(3)通过数据框的方式创建数据框

print("第三种方法创建DataFrame")

df4=df3[['one','three']]
print("数据框4:\n",df4)
print("数据框4的类型:",type(df4))
第三种方法创建DataFrame
数据框4:
    one  three
a    1      9
b    2     10
c    3     11
d    4     12
数据框4的类型: <class 'pandas.core.frame.DataFrame'>

1.(3)通过DataFrame中的某一行或某一列创建序列

直接拿出数据框3中第一列:

s3=df3['one'] #直接拿出数据框3中第一列
print("序列3:\n",s3)
print("序列3的类型:",type(s3))
序列3:
 a    1
b    2
c    3
d    4
Name: one, dtype: int64
序列3的类型: <class 'pandas.core.series.Series'>

直接拿出数据框3中第一行--iloc:

s4=df3.iloc[0] #df3['a'] #直接拿出数据框3中第一行--iloc
print("序列4:\n",s4)
print("序列4的类型:",type(s4))
序列4:
 one      1
two      5
three    9
Name: a, dtype: int64
序列4的类型: <class 'pandas.core.series.Series'>
  • 数据索引index

无论数据框还是序列,最左侧始终有一个非原始数据对象,这个就是接下来要介绍的数据索引。通过索引获取目标数据,对数据进行一系列的操作。

1.通过索引值或索引标签获取数据

s5=pd.Series(np.array([1,2,3,4,5,6]))
print(s5)
0    1
1    2
2    3
3    4
4    5
5    6
dtype: int32

如果不给序列一个指定索引值,序列会自动生成一个从0开始的自增索引。可以通过index查看序列的索引:

s5.index
RangeIndex(start=0, stop=6, step=1)

现在我们为序列设定一个自定义的索引值:

s5.index=['a','b','c','d','e','f'] #为index重新赋值
s5
a    1
b    2
c    3
d    4
e    5
f    6
dtype: int32

序列有了索引,就可以通过索引值或索引标签进行数据的获取:

print("s5[3]:\n", s5[3], "\n")
print("s5['e']:\n", s5['e'], "\n")
print("s5[[1,3,5]]:\n", s5[[1,3,5]], "\n")
print("s5[:4]:\n", s5[:4], "\n")
print("s5['c':]:\n", s5['c':], "\n")
print("s5['b':'e']:\n", s5['b':'e'], "\n")
s5[3]:
 4 

s5['e']:
 5 

s5[[1,3,5]]:
 b    2
d    4
f    6
dtype: int64 

s5[:4]:
 a    1
b    2
c    3
d    4
dtype: int64 

s5['c':]:
 c    3
d    4
e    5
f    6
dtype: int64 

s5['b':'e']:
 b    2
c    3
d    4
e    5
dtype: int64 

千万注意:如果通过索引标签获取数据的话,末端标签所对应的值是可以返回的!在一维数组中,就无法通过索引标签获取数据,这也是序列不同于一维数组的一个方面。

2.自动化对齐

如果有两个序列,需要对这两个序列进行算术运算,这时索引的存在就体现的它的价值了—自动化对齐。

s6=pd.Series(np.array([10,15,20,30,55,80]),index=['a','b','c','d','e','f'])
print("序列6:",s6)
s7=pd.Series(np.array([12,11,13,15,14,16]),index=['a','c','g','b','d','f'])
print("序列7:",s7)
序列6: a    10
b    15
c    20
d    30
e    55
f    80
dtype: int32
序列7: a    12
c    11
g    13
b    15
d    14
f    16
dtype: int32
print(s6+s7)
print(s6/s7)
a    22.0
b    30.0
c    31.0
d    44.0
e     NaN
f    96.0
g     NaN
dtype: float64
a    0.833333
b    1.000000
c    1.818182
d    2.142857
e         NaN
f    5.000000
g         NaN
dtype: float64

s6中不存在g索引,s7中不存在e索引,所以数据运算会产生两个缺失值NaN。可以注意到这里的算术运算自动实现了两个序列的自动对齐。对于数据框的对齐,不仅是行索引的自动对齐,同时也会对列索引进行自动对齐,数据框相当于二维数组的推广。

  • 利用pandas查询数据

这里的查询数据相当于R语言里的subset功能,可以通过布尔索引有针对的选取原数据的子集、指定行、指定列等。我们先导入一个student数据集:

student = pd.io.parsers.read_csv('student.csv')

查询数据的前5行或末尾5行:

student.head()
student.tail()

查询指定的行,这里的ix索引标签函数必须是中括号[]:

student.ix[[0,2,4,5,7]]

查询指定的列,如果多个列的话,必须使用双重中括号:

student[['Name','Height','Weight']].head()

也可以通过ix索引标签查询指定的列:

student.ix[:,['Name','Height','Weight']].head()

查询指定的行和列:

student.ix[[0,2,4,5,7],['Name','Height','Weight']].head()

以上是从行或列的角度查询数据的子集,现在我们来看看如何通过布尔索引实现数据的子集查询。
查询所有女生的信息:

student[student['Sex']=='F']

查询出所有12岁以上的女生信息:

student[(student['Sex']=='F') & (student['Age']>12)]

查询出所有12岁以上的女生姓名、身高和体重:

student[(student['Sex']=='F') & (student['Age']>12)][['Name','Height','Weight']]

上面的查询逻辑其实非常的简单,需要注意的是,如果是多个条件的查询,必须在&(且)或者|(或)的两端条件用括号括起来。

  • 统计分析

pandas模块为我们提供了非常多的描述性统计分析的指标函数,如总和、均值、最小值、最大值等:

a=np.random.normal(size=10)
d1=pd.Series(2*a+3)
d2=np.random.f(2,4,size=10)
d3=np.random.randint(1,100,size=10)
print(d1)
print(d2)
print(d3)
0    5.811077
1    2.963418
2    2.295078
3    0.279647
4    6.564293
5    1.146455
6    1.903623
7    1.157710
8    2.921304
9    2.397009
dtype: float64
[0.18147396 0.48218962 0.42565903 0.10258942 0.55299842 0.10859328
 0.66923199 1.18542009 0.12053079 4.64172891]
[33 17 71 45 33 83 68 41 69 23]
print("非空元素的计算:", d1.count())
print("最小值:", d1.min())
print("最大值:", d1.max())
print("最小值的位置:", d1.idxmin())
print("最大值的位置:", d1.idxmax())
print("10%分位数:", d1.quantile(0.1))
print("求和:", d1.sum())
print("平均数:", d1.mean())
print("中位数:", d1.median())
print("众数:", d1.mode())
print("方差:", d1.var())
print("标准差:", d1.std())
print("平均绝对偏差:", d1.mad())
print("偏度:", d1.skew())
print("峰度:", d1.kurt())
print("一次性输出多个描述性统计指标:", d1.describe())
非空元素的计算: 10
最小值: -0.11637919067128388
最大值: 5.649164574730916
最小值的位置: 0
最大值的位置: 9
10%分位数: 0.10224031600444726
求和: 24.301138139072435
平均数: 2.4301138139072433
中位数: 2.435626709867196
众数: 0   -0.116379
1    0.126531
2    0.901137
3    0.958300
4    1.935966
5    2.935288
6    3.231236
7    4.302453
8    4.377442
9    5.649165
dtype: float64
方差: 3.8995930522150966
标准差: 1.97473873011472
平均绝对偏差: 1.6690029678641687
偏度: 0.22234098279559492
峰度: -1.254241127357933
一次性输出多个描述性统计指标: count    10.000000
mean      2.430114
std       1.974739
min      -0.116379
25%       0.915427
50%       2.435627
75%       4.034649
max       5.649165
dtype: float64

必须注意的是,descirbe方法只能针对序列或数据框,一维数组是没有这个方法的。

这里自定义一个函数,将这些统计描述指标全部汇总到一起:

def stats(x):
    return pd.Series([x.count(),x.min(),x.idxmin(),x.quantile(.25),x.median(),
                     x.quantile(.75),x.mean(),x.max(),x.idxmax(),x.mad(),x.var(),x.std(),x.skew(),x.kurt()],
                     index=['Count','Min','Which_Min','Q1','Median','Q3','Mean','Max','Which_Max','Mad','Var','Std','Skew',
                           'Kurt'])

stats(d1)
Count        10.000000
Min           0.279647
Which_Min     3.000000
Q1            1.344189
Median        2.346044
Q3            2.952890
Mean          2.743961
Max           6.564293
Which_Max     4.000000
Mad           1.456849
Var           4.027872
Std           2.006956
Skew          1.045776
Kurt          0.393228
dtype: float64

当实际工作中我们需要处理的是一系列的数值型数据框,可以使用apply函数将这个stats函数应用到数据框中的每一列。

将之前创建的d1,d2,d3数据构建数据框:

df=pd.DataFrame(np.array([d1,d2,d3]).T,columns=['x1','x2','x3'])
print(df.head())
df.apply(stats)
         x1        x2    x3
0 -0.116379  0.494500  71.0
1  4.377442  2.154780  75.0
2  0.126531  1.198355  98.0
3  3.231236  0.667395  88.0
4  0.901137  0.711861  21.0
 x1x2x3
Count10.00000010.00000010.000000
Min-0.1163790.02480621.000000
Which_Min0.0000005.0000004.000000
Q10.9154270.30008839.500000
Median2.4356270.68962873.000000
Q34.0346491.02919091.750000
Mean2.4301140.75667365.800000
Max5.6491652.15478098.000000
Which_Max9.0000001.0000002.000000
Mad1.6690030.44288124.840000
Var3.8995930.384392923.733333
Std1.9747390.61999330.392982
Skew0.2223411.264177-0.634668
Kurt-1.2542412.047424

-1.351546

 以上很简单的创建了数值型数据的统计性描述,但对于离散型数据就不能使用该方法了。我们在统计离散变量的观测数、唯一值个数、众数水平及个数,只需要使用describe方法就可以实现这样的统计了:

student['Sex'].describe()

除了以上简单的描述性统计之外,还提供了连续变量的相关系数(corr)和协方差(cov)的求解:

df
 x1x2x3
05.8110770.18147433.0
12.9634180.48219017.0
22.2950780.42565971.0
30.2796470.10258945.0
46.5642930.55299833.0
51.1464550.10859383.0
61.9036230.66923268.0
71.1577101.18542041.0
82.9213040.12053169.0
92.3970094.64172923.0

 

df.corr()
 x1x2x3
x11.000000-0.075466-0.393609
x2-0.0754661.000000-0.437821
x3-0.393609-0.4378211.000000

 相关系数的计算方法可以调用pearson方法、kendall方法、或者spearman方法,默认使用的是pearson方法:

df.corr('spearman')
 x1x2x3
x11.0000000.260606-0.559273
x20.2606061.000000-0.510641
x3-0.559273-0.5106411.000000

 如果只关注某一个变量与其余变量的相关系数的话,可以使用corrwith,如下方只关注x1与其余变量的相关系数:

df.corrwith(df['x1'])
x1    1.000000
x2   -0.075466
x3   -0.393609
dtype: float64

数值型变量间的协方差矩阵:

df.cov()
 x1x2x3
x14.027872-0.208238-18.029331
x2-0.2082381.890358-13.738701
x3-18.029331-13.738701520.900000
  • pandas实现SQL操作

pandas实现对数据的增删改查

1.增:添加新行或增加新列

# 增:添加新行或增加新列
dict={'Name':['LiuShunxiang','Zhangshan'],
    'Sex':['M','F'],
    'Age':[27,23],
    'Height':[165.7,167.2],
    'weight':[61,63]}
print(dict)
student1=pd.DataFrame(dict)
print(student1)
{'Name': ['LiuShunxiang', 'Zhangshan'], 'Sex': ['M', 'F'], 'Age': [27, 23], 'Height': [165.7, 167.2], 'weight': [61, 63]}
           Name Sex  Age  Height  weight
0  LiuShunxiang   M   27   165.7      61
1     Zhangshan   F   23   167.2      63

现在将student2中的数据新增到student中,可以通过concat函数实现:

在数据库中union必须要求两张表的列顺序一致,而这里concat函数可以自动对齐两个数据框的变量。

添加新列:

对于新增的列没有赋值,就会出现空NaN的形式。

2.删:删除表、观测行或变量列

删除数据框student2,通过del命令实现,该命令可以删除Python的所有对象。

删除指定的行:

根据布尔索引删除行数据,其实这个删除就是保留删除条件的反面数据,例如删除所有14岁以下的学生:

删除指定的列:

不论是删除行还是删除列,都可以通过drop方法实现,只需要设定好删除的轴即可,即调整drop方法中的axis参数。默认该参数为0,表示删除行观测,如果需要删除列变量,则需设置为1。

3.改:修改原始记录的值

如果发现表中的某些数据错误了,如何更改原来的值呢?我们试试结合布尔索引和赋值的方法:
例如发现student3中姓名为Liushunxiang的学生身高错了,应该是170,如何改呢?

4.查:类似上边的数据查询部分

5.聚合:通过groupby()函数实现数据的聚合操作

根据性别分组,计算各组别中学生身高和体重的平均值:

如果不对原始数据作限制的话,聚合函数会自动选择数值型数据进行聚合计算。如果不想对年龄计算平均值的话,就需要剔除改变量:

groupby还可以使用多个分组变量,例如根据年龄和性别分组,计算身高与体重的平均值:

还可以对每个分组计算多个统计量:

6.排序

可以使用order、sort_index和sort_values实现序列和数据框的排序工作:

再试试降序排序的设置:

上面两个结果其实都是按值排序,并且结果中都给出了警告信息,即建议使用sort_values()函数进行按值排序。

在数据框中一般都是按值排序,例如:

7.多表连接

连接分内连接和外连接,在数据库语言中通过join关键字实现,pandas建议使用merger函数实现数据的各种连接操作。

如下是构造一张学生的成绩表:

现在想把学生表student与学生成绩表score做一个关联,该如何操作呢?

注意,默认情况下,merge函数实现的是两个表之间的内连接,即返回两张表中共同部分的数据。可以通过how参数设置连接的方式,left为左连接;right为右连接;outer为外连接。

左连接实现的是保留student表中的所有信息,同时将score表的信息与之配对,能配多少配多少,对于没有配对上的Name,将会显示成绩为NaN。

  • 缺失值处理

现实中的数据存在很多噪音的同时,缺失值也非常的常见。缺失值的存在会影响后期的数据分析或挖掘工作,那么缺失值的处理有哪些方法呢?

1.删除法

当数据中某个变量大部分值都会缺失值时,可以考虑删除该变量;
当缺失值时随机分布的,且缺失的数量并不是很多时,可以删除这些缺失的观测;

这是一组含有缺失值的序列,我们可以结合sum函数和isnull函数来检测数据中含有多少缺失值:

sum(pd.isnull(s))

直接删除缺失值:

默认情况下,dropna会删除任何含有缺失值的行,我们再构造一个数据框试试:

返回结果表明,数据中只要含有缺失值NaN,该数据行就会被删除,如果使用参数how=’all’,则表明只删除所有行为缺失值的观测。

2.替补法

对于连续变量,如果变量的分布近似或就是正态分布的话,可以用均值替代那些缺失值;
如果变量是有偏的,可以使用中位数来代替那些缺失值;
对于离散型变量,一般使用众数去替换那些存在缺失的预测;

fillna函数的参数:

value:用于填充缺失值的标量值或者字典对象
method:插值方式,如果函数调用时,未指定其他参数的话默认值fill
axis:待填充的轴默认值axis=0
inplace:修改调用这对象而不产生副本
limit:(对于前向和后项填充)可以连续填充的最大数量

1)用0填补所有缺失值

2)采用前项填充或后向填充

3)使用常量填充不同的列

4)用均值或中位数填充各自的列

3.插补法

插补法是基于蒙特卡洛模拟法,结合线性模型、广义线性模型、决策树等方法计算出来的预测值替换缺失值。

  • 实现excel的数据透视表功能

在Excel中有一个非常强大的功能就是数据透视表,通过托拉拽的方式可以迅速的查看数据的聚合情况,这里的聚合可以是计数、求和、均值、标准差等。
pandas为我们提供了非常强大的函数pivot_table(),该函数就是实现数据透视表功能的。对于上面所说的一些聚合函数,可以通过参数aggfunc设定。先看看这个函数的语法和参数:

pivot_table(data,values=None,index=None,columns=None,aggfunc='mean', fill_value=None,margins=False,dropna=True,margins_name='All')

data:需要进行数据透视表操作的数据框
values:指定需要聚合的字段
index:指定某些原始变量作为行索引
columns:指定哪些离散的分组变量
aggfunc:指定相应的聚合函数
fill_values:使用一个常数替代缺失值,默认不替换
margins:是否进行行或列的汇总,默认不汇总
dropna:默认所有观测为缺失的列
margins_name:默认行汇总或列汇总的名称为‘ALL’

仍然以student表为例,来认识一下数据透视表pivot_table函数的用法:

对一个分组变量(Sex),一个数值变量(Height)作统计汇总:

对一个分组变量(Sex),两个数值变量(Height,Weight)作统计汇总:

对两个分组变量(Sex,Age),两个数值变量(Height,Weight)作统计汇总:

很显然这样的结果并不像Excel中预期的那样,该如何变成列联表的形式的?很简单,只需将结果进行非堆叠操作(unstack)即可:

使用多个聚合函数:

  • 多层索引的使用

接下再讲一个Pandas中的重要功能,那就是多层索引。
序列的多层索引类似于Excel中如下形式。

对于这样的数据格式有什么好处呢?pandas可以帮我们实现用低维度形式处理高维数数据,这里举个例子:

对于这种多层次索引的序列,取数据就显得非常简单了:

对于这种多层次索引的序列,我们还可以非常方便的将其转换为数据框的形式:

以上针对的是序列的多层次索引,数据框也同样有多层次的索引,而且每条轴上都可以有这样的索引,就类似于Excel中常见的这种形式:

构造一个类似的高维数据框:

同样,数据框中的多层索引也可以非常便捷的取出大块数据:

在数据框中使用多层索引,可以将整个数据集控制在二维表结构中,这对于数据重塑和基于分组的操作(如数据透视表的生成)比较有帮助。

就拿student二维数据框为例,我们构造一个多层索引数据集:

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值