python 数据分析6 pandas入门

六、pandas 入门

pandas 是一个 python 库,含有使数据清洗和分析工作变得更快更简单的数据结构和操作工具。

经常和其他工具一起使用,如数值计算工具 NumPy 和 SciPy,分析库 statsmodels 和 scikit-learn,和数据可视化库 matplotlib。

基于NumPy数组构建,特别是基于数组的函数和不使用 for 循环的数据处理。(pandas 处理表格和混杂数据,NumPy 更适合处理统一的数值数组数据)

常用引入方法:

import pandas as pd
from pandas import Series, DataFrame

1、数据结构

两个主要数据结构:Series(一维) 和 DataFrame(二维)。

Series

Series 是一种类似于一维数组的对象,它由一组数据(各种NumPy数据类型)以及一组与之相关的数据标签(即索引)组成。

索引

Series的字符串表现形式为:索引在左边,值在右边。

obj = pd.Series([4, 7, -5, 3])

# 自动创建整数型索引
obj
0 4
1 7
2 -5
3 3
dtype: int64

obj.values # array([ 4, 7, -5, 3])
obj.index # RangeIndex(start=0, stop=4, step=1)

带标记的索引:

obj2 = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])

obj2
d 4
b 7
a -5
c 3
dtype: int64

obj2.index # Index(['d', 'b', 'a', 'c'], dtype='object')

通过索引选定值:

obj2['a'] # -5
obj2['d'] = 6
obj2[['c', 'a', 'd']]
c 3
a -5
d 6
dtype: int64

通过赋值修改索引:

obj:
0 4
1 7
2 -5
3 3
dtype: int64

obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']

obj:
Bob 4
Steve 7
Jeff -5
Ryan 3
dtype: int64

使用 NumPy 函数或类似 NumPy 的运算会保留索引值的链接:

obj2[obj2 > 0]
d 6
b 7
c 3
dtype: int64

obj2 * 2
d 12
b 14
a -10
c 6
dtype: int64

np.exp(obj2)
d 403.428793
b 1096.633158
a 0.006738
c 20.085537
dtype: float64
字典

把 Series 看成定长有序字典

'b' in obj2 # True
'e' in obj2 # False

通过字典创建 Series:(可以传入排好序的字典的键以改变顺序)

sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
obj3 = pd.Series(sdata)

states = ['California', 'Ohio', 'Oregon', 'Texas']
obj4 = pd.Series(sdata, index=states)

isnull 和 notnull函数用于检测缺失数据 NaN:

pd.isnull(obj4)
pd.notnull(obj4)
obj4.isnull()

数据对齐功能:根据运算的索引标签自动对齐数据(类似于数据库的 join 操作)

属性

Series对象本身及其索引都有一个 name 属性

obj4.name = 'population'
obj4.index.name = 'state'

obj4
state
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
Name: population, dtype: float64

DataFrame

DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。

既有行索引也有列索引,可以看做由Series组成的字典(共用同一个索引)。

创建

最常用的一种是直接传入一个由等长列表或NumPy数组组成的字典:

data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
'year': [2000, 2001, 2002, 2001, 2002, 2003],
'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
frame = pd.DataFrame(data)

DataFrame 会自动加上索引(跟Series一样),且全部列会被有序排列:

frame

   pop state year
0 1.5 Ohio 2000
1 1.7 Ohio 2001
2 3.6 Ohio 2002
3 2.4 Nevada 2001
4 2.9 Nevada 2002
5 3.2 Nevada 2003

对于特别大的DataFrame,head方法会选取前五行

frame.head()

指定了列序列,则DataFrame的列就会按照指定顺序进行排列:

pd.DataFrame(data, columns=['year', 'state', 'pop'])

如果传入的列在数据中找不到,就会在结果中产生缺失值 NaN

取值赋值

通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series。(返回的Series拥有原DataFrame相同的索引,且其name属性也已经被相应地设置好了)

frame2['state'] # 任何列名
frame2.year # 列名必须合理

获取行,用 loc 属性:

frame2.loc['three']

通过赋值修改列:

frame2['debt'] = 16.5
frame2['debt'] = np.arange(6.)

将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值:

val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
frame2['debt'] = val

删除列:

del frame2['eastern']
字典

用字典创建 DataFrame:

pop = {'Nevada': {2001: 2.4, 2002: 2.9}, 'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}

frame3 = pd.DataFrame(pop)
frame3:
       Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6

对 DataFrame 进行转置(内层字典的键会被合并、排序以形成最终的索引):

frame3.T
          2000 2001 2002
Nevada NaN 2.4 2.9
Ohio 1.5 1.7 3.6

明确指定索引:

pd.DataFrame(pop, index=[2001, 2002, 2003])
        Nevada Ohio
2001 2.4 1.7
2002 2.9 3.6
2003 NaN NaN

可以输入给 DataFrame 构造器的数据
在这里插入图片描述

属性

设置 DataFrame 的 index 和 columns 的 name 属性:

frame3.index.name = 'year'; frame3.columns.name = 'state'
frame3:
state Nevada Ohio
year
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6

values 属性也会以二维 ndarray 的形式返回 DataFrame 中的数据:

frame3.values
array([[ nan, 1.5],
        [ 2.4, 1.7],
        [ 2.9, 3.6]])

索引对象 index

构建 Series 或 DataFrame时,所用到的任何数组或其他序列的标签都会被转换成一个 Index 对象(不可变):

obj = pd.Series(range(3), index=['a', 'b', 'c'])
index = obj.index
index # Index(['a', 'b', 'c'], dtype='object')
index[1:] # Index(['b', 'c'], dtype='object')

除了类似于数组,Index的功能也类似一个固定大小的集合:

frame3:
state Nevada Ohio
year
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6

frame3.columns
Index(['Nevada', 'Ohio'], dtype='object', name='state')

'Ohio' in frame3.columns # True
2003 in frame3.index # False

pandas的 Index 可以包含重复的标签,选择重复的标签,会显示所有的结果。

Index 方法和属性:
在这里插入图片描述

2、基本功能

重新索引 reindex

reindex 用于创建一个新对象,数据符合新索引:

obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
obj:
d 4.5
b 7.2
a -5.3
c 3.6
dtype: float64

obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
obj2:
a -5.3
b 7.2
c 3.6
d 4.5
e NaN
dtype: float64

插值处理。method选项使用 ffill 可以实现前向值填充:

obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
obj3
0 blue
2 purple
4 yellow
dtype: object

obj3.reindex(range(6), method='ffill')
0 blue
1 blue
2 purple
3 purple
4 yellow
5 yellow
dtype: object

借助DataFrame,reindex可以修改(行)索引和列。

frame = pd.DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'], columns=['Ohio', 'Texas', 'California'])
frame
    Ohio Texas California
a 0 1 2
c 3 4 5
d 6 7 8

# 修改行索引
frame2 = frame.reindex(['a', 'b', 'c', 'd'])
frame2
    Ohio Texas California
a 0.0 1.0 2.0
b NaN NaN NaN
c 3.0 4.0 5.0
d 6.0 7.0 8.0

# 修改列
states = ['Texas', 'Utah', 'California']
frame.reindex(columns=states)
    Texas Utah California
a 1 NaN 2
c 4 NaN 5
d 7 NaN 8

reindex 函数的参数
在这里插入图片描述

丢弃指定轴上的项 drop

只需一个索引数组或列表。

drop方法返回的是一个在指定轴上删除了指定值的新对象。

Series 对象:

obj = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
new_obj = obj.drop('c')
obj.drop(['d', 'c'])

DataFrame 对象:

data = pd.DataFrame(np.arange(16).reshape((4, 4)), index=['Ohio', 'Colorado', 'Utah', New York'], columns=['one', 'two', 'three', 'four'])

# 删除行的值
data.drop(['Colorado', 'Ohio'])

# 删除列的值
data.drop('two', axis=1)
data.drop(['two', 'four'], axis='columns')

只修改对象,不返回新对象

obj.drop('c', inplace=True)

索引、选取和过滤

Series:
Series 索引(obj[…])的工作方式类似于NumPy数组的索引,只不过Series的索引值不只是整数。

obj = pd.Series(np.arange(4.), index=['a', 'b', 'c', 'd'])

obj['b']
obj[1]
obj[2:4]
obj[['b', 'a', 'd']]
obj[[1, 3]]
obj[obj < 2]

利用标签的切片运算与普通的Python切片运算不同,其末端是包含的

obj['b':'c'] = 5
obj
a 0.0
b 5.0
c 5.0
d 3.0
dtype: float64

DataFrame
用一个值或序列对DataFrame进行索引其实就是获取一个或多个列:

data = pd.DataFrame(np.arange(16).reshape((4, 4)), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['one', 'two', 'three', 'four'])

data
     one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15

# 选取列
data['two']
data[['three', 'one']]

# 切片选取行

# 选取第三列大于5的值所在行
data[data['three'] > 5]

索引函数 loc 和 iloc

对于 DataFrame,可以使用轴标签(loc)或整数索引(iloc),从DataFrame
选择行和列的子集。

data
     one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15

通过 loc 和标签选择一行和多列:

data.loc['Colorado', ['two', 'three']]

然后用 iloc 和整数进行选取:

data.iloc[2, [3, 0, 1]] # 第三行的某三列
data.iloc[2] # 第三行
data.iloc[[1, 2], [3, 0, 1]] #第二三行的某三列

使用切片:

data.loc[:'Utah', 'two']
data.iloc[:, :3][data.three > 5]

DataFrame 选取和重新组合数据方法:
在这里插入图片描述

整数索引

ser = pd.Series(np.arange(3.))
ser
0 0.0
1 1.0
2 2.0
dtype: float64

ser[:1] # 第一行
ser.loc[:1] # 前两行
ser.iloc[:1] # 第一行

运算、对齐和填充

Series和DataFrame的算术方法:
在这里插入图片描述
对不同索引对象做算数运算,自动的数据对齐操作在不重叠的索引处引入了NA值。缺失值会在算术运算过程中传播。

df1 = pd.DataFrame({'A': [1, 2]})
df2 = pd.DataFrame({'B': [3, 4]})
df1
    A
0 1
1 2

df2
    B
0 3
1 4

df1 - df2
    A    B
0 NaN NaN
1 NaN NaN

当一个对象中某个轴标签在另一个对象中找不到时填充一个特殊值(比如0),用 fill_value。

df1.add(df2, fill_value=0)

DataFrame和Series之间的运算

默认情况下,DataFrame和Series之间的算术运算会将Series的索引匹配到DataFrame的列,然后沿着行一直向下广播:

frame
        b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0

series
b 0.0
d 1.0
e 2.0
Name: Utah, dtype: float64

frame - series
        b d e
Utah 0.0 0.0 0.0
Ohio 3.0 3.0 3.0
Texas 6.0 6.0 6.0
Oregon 9.0 9.0 9.0

如果某个索引值在 DataFrame 的象就会被重新索引以形成并集

series2 = pd.Series(range(3), index=['b', 'e', 'f'])

frame + series2
        b d e f
Utah 0.0 NaN 3.0 NaN
Ohio 3.0 NaN 6.0 NaN
Texas 6.0 NaN 9.0 NaN
Oregon 9.0 NaN 12.0 NaN

如果匹配行且在列上广播,则必须使用算术运算方法:

series3 = frame['d'] # 选取某一列
frame.sub(series3, axis='index') # 传入的轴号就是希望匹配的轴 index 或 0

函数应用和映射 apply 和 applymap

NumPy 的 ufuncs(元素级数组方法)也可用于操作 pandas 对象,也可以将函数应用到由各列或行所形成的一维数组上(使用 apply ):

f = lambda x: x.max() - x.min()
frame.apply(f) # 应用在每列,结果是一个Series
frame.apply(f, axis='columns') # 应用在每行

许多最为常见的数组统计功能都被实现成DataFrame的方法(如sum和mean),因此无需使用 apply 方法。

传递到apply的函数可以返回由多个值组成的 Series :

def f(x):
    return pd.Series([x.min(), x.max()], index=['min','max'])

元素级的Python函数也是可以用的。假如你想得到frame中各个浮点值的格式化字符串,使用 applymap 即可:

format = lambda x: '%.2f' % x
frame.applymap(format)

排序和排名

按索引排序 sort_index

按索引进行排序(按字典顺序),可使用 sort_index 方法,返回一个已排序的新对象:

# Series
obj = pd.Series(range(4), index=['d', 'a', 'b', 'c'])
obj.sort_index()

# DataFrame
frame = pd.DataFrame(np.arange(8).reshape((2, 4)),
        index=['three', 'one'],
        columns=['d', 'a', 'b', 'c'])
frame.sort_index() # 按行排
frame.sort_index(axis=1) # 按列排

默认升序,也可降序(ascending关键字):

frame.sort_index(axis=1, ascending=False)
按值排序 sort_values

Series 排序时,任何缺失值默认都会被放到末尾;DataFrame 排序时,将一个
或多个列的名字传递给 sort_values 的 by 选项。

# Series
obj = pd.Series([4, np.nan, 7, np.nan, -3, 2])
obj.sort_values()

# DataFrame
frame = pd.DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
frame.sort_values(by='b')
frame.sort_values(by=['a', 'b'])
排名 rank

rank 方法默认为各组分配一个平均排名:

obj = pd.Series([7, -5, 7, 4, 2, 0, 4])
obj.rank() 
obj.rank(method='first') # 根据值在原数据中出现的顺序
obj.rank(ascending=False, method='max') # 按降序排名

所有用于破坏平级关系的method选项:
在这里插入图片描述

带有重复标签的轴索引

obj = pd.Series(range(5), index=['a', 'a', 'b', 'b', 'c'])
obj
a 0
a 1
b 2
b 3
c 4
dtype: int64

obj.index.is_unique # False

数据选取。对应多值,返回一个 Series,对应单值,返回一个标量值:

obj['a'] 
a 0
a 1
dtype: int64

obj['c']
4

3、汇总和计算描述统计

pandas 对象拥有一组常用的数学和统计方法,大部分都属于约简和汇总统计。
(基于没有缺失数据的假设而构建)
在这里插入图片描述

相关系数与协方差

Series的 corr 方法用于计算两个Series中重叠的、非NA的、按索引对齐的值的相关系数。与此类似,cov 用于计算协方差。

唯一值、值计数以及成员资格

unique 可以得到 Series 中的唯一值数组;value_counts 用于计算一个Series中各值出现的频率。

obj.unique()
obj.value_counts()

value_counts 还是一个顶级 pandas 方法,可用于任何数组或序列:

pd.value_counts(obj.values, sort=False)

在这里插入图片描述

原创文章 46 获赞 36 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_38673554/article/details/104237355