Pandas入门

Pandas 是 Python 的核心数据分析支持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据。Pandas 的目标是成为 Python 数据分析实践与实战的必备高级工具,其长远目标是成为最强大、最灵活、可以支持任何语言的开源数据分析工具。经过多年不懈的努力,Pandas 离这个目标已经越来越近了。

Pandas 适用于处理以下类型的数据:

  • 与 SQL 或 Excel 表类似的,含异构列的表格数据;
  • 有序和无序(非固定频率)的时间序列数据;
  • 带行列标签的矩阵数据,包括同构或异构型数据;
  • 任意其它形式的观测、统计数据集, 数据转入 Pandas 数据结构时不必事先标记。

Pandas 的主要数据结构是 Series(一维数据)与 DataFrame(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型用例。对于 R 用户,DataFrame 提供了比 R 语言 data.frame 更丰富的功能。Pandas 基于 NumPy 开发,可以与其它第三方科学计算支持库完美集成。

Pandas 数据结构

Series

Series是一种类似于一维数组的对象,由下面两个部分组成:

  • values:一组数据(ndarray类型)
  • index:相关的数据索引标签

Series的创建

由列表或numpy数组创建
1
2
3
4
5
6
7
8
9
10
11
12
from pandas import Series
l = [i for i in range(6)]
s = Series(l,index=list('abcdef'))
s

a 0
b 1
c 2
d 3
e 4
f 5
dtype: int64
1
2
3
4
5
6
7
8
9
10
11
# 还可以通过设置index参数指定索引
s.index = [2,4,6,8,10,12]
s

2 0
4 1
6 2
8 3
10 4
12 5
dtype: int64
由字典创建
1
2
3
4
5
6
7
8
9
# 字典的key对应Series的索引
s = Series({'a':1, 'b':2, 'c':3, 'd': 4})
s

a 1
b 2
c 3
d 4
dtype: int64

Series的索引和切片

可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的仍然是一个Series类型)。分为显示索引和隐式索引:

显式索引:
  • 使用index中的元素作为索引值
  • 使用.loc[](推荐)

注意,此时是闭区间

image-20220710110343599

隐式索引:
  • 使用整数作为索引值
  • 使用.iloc[](推荐)

注意,此时是半开区间

image-20220710110727110

Series的基本概念

可以把Series看成一个定长的有序字典

可以通过shape,size,index,values等得到series的属性

1
2
3
4
5
6
7
8
s

a 1
b 2
c 3
d 4
dtype: int64

1
2
3
4
5
6
7
8
9
10
11
12
s.shape
(4,)

s.size
4

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

s.values
array([1, 2, 3, 4], dtype=int64)

可以通过head(),tail()快速查看Series对象的样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
s.head(3)

a 1
b 2
c 3
dtype: int64

s.tail(4)

a 1
b 2
c 3
d 4
dtype: int64

当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况

1
2
3
4
5
6
7
8
s.loc[0] = np.nan

a 1.0
b 2.0
c 3.0
d 4.0
0 NaN
dtype: float64

可以使用pd.isnull(),pd.notnull(),或自带isnull(),notnull()函数检测缺失数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
pd.isnull(s)

a False
b False
c False
d False
0 True
dtype: bool


pd.notnull(s)
a True
b True
c True
d True
0 False
dtype: bool


s.isnull()

a False
b False
c False
d False
0 True
dtype: bool


s.notnull()
a True
b True
c True
d True
0 False
dtype: bool

Series对象本身及其实例都有一个name属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
s.name = 'Series s'

s

a 1.0
b 2.0
c 3.0
d 4.0
0 NaN
Name: Series s, dtype: float64

Series.name = 'Name'

s

a 1.0
b 2.0
c 3.0
d 4.0
0 NaN
Name: Series s, dtype: float64

Series的运算

适用于numpy的数组运算也适用于Series
1
2
3
4
5
6
7
8
s + 1 

a 2.0
b 3.0
c 4.0
d 5.0
0 NaN
Name: Series s, dtype: float64
Series之间的运算
  • 在运算中自动对齐不同索引的数据
  • 如果索引不对应,则补NaN
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
s1 = Series(np.random.randint(0,10,size=4),index=np.arange(0,4))

s1

0 1
1 1
2 9
3 3
dtype: int32


s2 = Series(np.random.randint(0, 10, size=4), index=np.arange(2, 6))

s2

2 1
3 4
4 7
5 9
dtype: int32


s1 + s2
# 相同的索引进行运算,不同的索引补NaN

0 NaN
1 NaN
2 10.0
3 7.0
4 NaN
5 NaN
dtype: float64
  • 注意:要想保留所有的index,则需要使用.add()函数
1
2
3
4
5
6
7
8
9
10
# 使用pandas封装的运算函数,保留所有index对应value
s1.add(s2, fill_value=0)

0 1.0
1 1.0
2 10.0
3 7.0
4 7.0
5 9.0
dtype: float64

DataFrame

DataFrame是一个【表格型】的数据结构,可以看做是【由Series组成的字典】(共用同一个索引)。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到二维。DataFrame既有行索引,也有列索引。

  • 行索引:index
  • 列索引:columns
  • 值:values(numpy的二维数组)

DataFrame的创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from  pandas import DataFrame

# 分块创建
data = np.random.randint(0,150, size=(4,4))
index = ['张三', '李四', '王五', '赵六']
columns = ['语文', '数学', '英语','python']
df = DataFrame(data=data, index=index, columns=columns)
df


# 字典创建
df = DataFrame({'语文': np.random.randint(0,150, size=4), '数学': np.random.randint(0,150, size=4), '英语': np.random.randint(0,150, size=4), 'python': np.random.randint(0,150, size=4)},
)

df.index = ['张三', '李四', '王五', '赵六']

df

image-20220710143524992

DataFrame属性:values、columns、index、shape

1
2
3
4
5
6
7
8
9
10
11
12
13
14
df.values
array([[ 74, 19, 132, 116],
[ 43, 90, 16, 42],
[135, 37, 58, 42],
[ 91, 9, 104, 51]])

df.columns
Index(['语文', '数学', '英语', 'python'], dtype='object')

df.index
Index(['张三', '李四', '王五', '赵六'], dtype='object')

df.shape
(4, 4)

DataFrame的索引

对列进行索引
  • 通过类似字典的方式
  • 通过属性的方式

可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。

image-20220710150634683

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
df['语文']

张三 30
李四 17
王五 77
赵六 102
Name: Name, dtype: int32


df.语文

张三 74
李四 43
王五 135
赵六 91
Name: 语文, dtype: int32

1
2
3
# 新增一列
df['计算机'] = np.random.randint(0,150, size=4)
df

image-20220710150748057

1
2
# 新增一列的时候不能使用属性的写法
# df.理综 = np.random.randint(0,150, size=4)

image-20220710150955679

1
2
3
# 列切片
df['数学 ': 'python']
# 直接使用中括号,接冒号,是在进行行切片.

image-20220710151053690

1
df[['数学', '英语', 'python']]

image-20220710151113939

1
df.iloc[:, 1:4]

image-20220710151217348

对行进行索引
  • 使用.loc[]加index来进行行索引
  • 使用.iloc[]加整数来进行行索引

同样返回一个Series,index为原来的columns。

image-20220710151857311

对元素进行索引
  • 使用列索引

  • 使用行索引(iloc[3,1]相当于两个参数;iloc[[3,3]] 里面的[3,3]看做一个参数)

  • 使用values属性(二维numpy数组)

image-20220710152641101

DataFrame 索引总结
  1. 行索引用.loc, 列索索引用中括号.
  2. 对元素的索引,先索引行,再索引列. df.loc[index, columns]
  3. 如果还想返回DataFrame,那么使用两层中括号.

【注意】 直接用中括号时:

  • 索引表示的是列索引
  • 切片表示的是行切片

DataFrame的运算

DataFrame之间的运算

同Series一样:

  • 在运算中自动对齐不同索引的数据
  • 如果索引不对应,则补NaN
Series与DataFrame之间的运算

【重要】

  • 使用Python操作符:以行为单位操作(参数必须是行),对所有行都有效。(类似于numpy中二维数组与一维数组的运算,但可能出现NaN)

  • 使用pandas操作函数:

    1
    2
    axis=0:以列为单位操作(参数必须是列),对所有列都有效。
    axis=1:以行为单位操作(参数必须是行),对所有行都有效。
归纳,总结
1
2
3
4
1, DataFrame和单个数字运算,每个元素分别运算.
2, DataFrame和DataFrame运算,相同的行列索引进行运算,不同索引补NaN.
3, DataFrame和Series运算,使用运算符的时候,默认比较DataFrame的列索引和Series的索引.
4, 如果想保留原始数据,或者改变运算的方向,使用pandas封装的方法.