Jarvis' Blog (总有美丽的风景让人流连) 总有美丽的风景让人流连

Python 第三方库 —— Pandas

2020-02-02
Jarvis
Wiki_Python

Pandas中有两种基础类型: SeriesDataFrame

1
import pandas as pd

1. 构建 DataFrame

  • 从数组构建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
data = np.array(
    [[1, 1, 1],
     [2, 2, 2],
     [3, 3, 3],
     [4, 4, 1],
     [5, 5, 2],
     [6, 6, 3]],
    dtype=np.float32
)

df = pd.DataFrame(data, index=[0, 1, 2, 3, 4, 5], columns=[0, "A", "B"])
print(df)

#	0	A	B
# 0	1.0	1.0	1.0
# 1	2.0	2.0	2.0
# 2	3.0	3.0	3.0
# 3	4.0	4.0	1.0
# 4	5.0	5.0	2.0
# 5	6.0	6.0	3.0

Note: DataFrame 中的行指标名称index 表示, 列指标名称column 表示. 行列指标名称既可以为数字, 也可以为字符串. 不指定时默认为数字

  • 从文件构建(比如 csv)
1
df = pd.read_csv("data.csv")

2. 索引 DataFrame

2.1 列名称索引 –> 返回 Series 类型

  • 以字典的形式通过列名称索引(适用于列名称为数字和字符串)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
print(df["A"])

# 0    1.0
# 1    2.0
# 2    3.0
# 3    1.0
# 4    2.0
# 5    3.0
# Name: A, dtype: float32

print(df[0])

# 0    1.0
# 1    2.0
# 2    3.0
# 3    4.0
# 4    5.0
# 5    6.0
# Name: 0, dtype: float32
  • 以属性的形式通过列名称索引(只适用于列指标为字符串)
1
2
3
4
5
6
7
8
9
df.A

# 0    1.0
# 1    2.0
# 2    3.0
# 3    1.0
# 4    2.0
# 5    3.0
# Name: A, dtype: float32

2.2 多个列名称索引 –> 返回 DataFrame 类型

  • 把原来的单个索引替换为指标名称的列表即可
1
2
3
4
5
6
7
8
9
print(df[[0, "A"]])

# 	0	A
# 0	1.0	1.0
# 1	2.0	2.0
# 2	3.0	3.0
# 3	4.0	1.0
# 4	5.0	2.0
# 5	6.0	3.0

2.3 行切片索引 –> 返回 DataFrame 类型

  • 通过行指标序号的切片索引
1
2
3
4
5
6
7
8
9
10
11
print(df[1:2])

# 	0	A	B
# 1	2.0	2.0	2.0

print(df[1:3])
# 等价于 df[slice(1, 3)]

# 	0	A	B
# 1	2.0	2.0	2.0
# 2 3.0 3.0	3.0

!!! Note: 使用行指标切片时为左闭右开.

  • 使用布尔数组/布尔 Series 作为索引
1
2
3
4
5
6
7
df[df[0] > 3]
# 等价于 df[[False, False, False, True, True, True]]

# 	0	A	B
# 3	4.0	4.0	1.0
# 4	5.0	5.0	2.0
# 5	6.0	6.0	3.0

Note: 这里不能使用布尔DataFrame

2.4 同时索引行和列

  • 使用 df.ix 的索引已经过期, 不推荐再使用
  • 使用 df.loc 进行名称索引
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
37
38
39
df.loc[[0, 1, 2], [0, "A"]]

# 	0	A
# 0	1.0	1.0
# 1	2.0	2.0
# 2	3.0	3.0

df.loc[:2, [0, "A"]]

# 	0	A
# 0	1.0	1.0
# 1	2.0	2.0
# 2	3.0	3.0

df.loc[:2, "A"]

# 0    1.0
# 1    2.0
# 2    3.0
# Name: A, dtype: float32

df.loc[3:, "A":"B"]
# 等价于 df.loc[slice(0, 2), slice("A", "B")]

# 	A	B
# 0	4.0	1.0
# 1	5.0	2.0
# 2	6.0	3.0

df.loc[3, "A"]

# 4.0

df.loc[:1]
# 不指定列则等价于索引所有列

# 	0	A	B
# 0	1.0	1.0	1.0
# 1	2.0	2.0	2.0

!!! Note: 使用 loc 的行名称切片时为左闭右闭 (注意和前面的区分).

  • 使用 df.iloc 进行指标序号索引. 这里的索引方式和 Numpy 完全相同
1
2
3
4
5
6
7
8
9
10
11
df.iloc[:3, :2]

# 	0	A
# 0	1.0	1.0
# 1	2.0	2.0
# 2	3.0	3.0

df.iloc[3, 1]
df

# 4.0

!!! Note: 使用 iloc 的行指标切片时为左闭右开 (注意和前面的区分).

2.5 允许出现相同的行名称或列名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
data = np.array(
    [[1, 2, 3, 4, 5, 6],
     [1, 2, 3, 4, 5, 6],
     [1, 2, 3, 1, 2, 3],
     [3, 2, 1, 1, 2, 3],],
    dtype=np.float32
)

df = pd.DataFrame(data, index=[0, 1, 0, 1], columns=list(ABCABC))
print(df)

#      A    B    C    A    B    C
# 0  1.0  2.0  3.0  4.0  5.0  6.0
# 1  1.0  2.0  3.0  4.0  5.0  6.0
# 0  1.0  2.0  3.0  1.0  2.0  3.0
# 1  3.0  2.0  1.0  1.0  2.0  3.0
  • 此时用行/列名称索引时会同时获得多行/列
1
2
3
4
5
6
7
print(df["A"])

#      A    A
# 0  1.0  4.0
# 1  1.0  4.0
# 0  1.0  1.0
# 1  3.0  1.0
  • 行名称不唯一时, 使用loc来索引名称不可使用切片
1
2
3
4
5
6
7
8
9
print(df.loc[0])

#      A    B    C    A    B    C
# 0  1.0  2.0  3.0  4.0  5.0  6.0
# 0  1.0  2.0  3.0  1.0  2.0  3.0

print(df.loc[0:1])

# KeyError 报错
  • 行指标序号直接索引不受影响

3. 修改 DataFrame

3.1 增加

  • 增加列
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
df["C"] = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
print(df)
# 提供所有值

# 	0	A	B	C
# 0	1.0	1.0	1.0	Mon
# 1	2.0	2.0	2.0	Tue
# 2	3.0	3.0	3.0	Wed
# 3	4.0	4.0	1.0	Thu
# 4	5.0	5.0	2.0	Fri
# 5	6.0	6.0	3.0	Sat

df["D"] = 10
print(df)
# 提供一个值

# 	0	A	B	C	D
# 0	1.0	1.0	1.0	Mon	10
# 1	2.0	2.0	2.0	Tue	10
# 2	3.0	3.0	3.0	Wed	10
# 3	4.0	4.0	1.0	Thu	10
# 4	5.0	5.0	2.0	Fri	10
# 6	6.0	6.0	3.0	Sat	10
  • 增加行, 只能使用 loc , 不能用 iloc .
1
2
3
4
5
6
7
8
9
10
11
df.loc[7] = [7., 7., 1., "Sun", 10]
print(df)

# 	0	A	B	C	D
# 0	1.0	1.0	1.0	Mon	10
# 1	2.0	2.0	2.0	Tue	10
# 2	3.0	3.0	3.0	Wed	10
# 3	4.0	4.0	1.0	Thu	10
# 4	5.0	5.0	2.0	Fri	10
# 5	6.0	6.0	3.0	Sat	10
# 6	7.0	7.0	1.0	Sun	10

3.2 删除

  • 删除列
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
df.drop("A", axis=1)
# 指定 axis=1 表示指标"A"是列指标

# 	0	B	C	D
# 0	1.0	1.0	Mon	10
# 1	2.0	2.0	Tue	10
# 2	3.0	3.0	Wed	10
# 3	4.0	1.0	Thu	10
# 4	5.0	2.0	Fri	10
# 5	6.0	3.0	Sat	10
# 6	7.0	1.0	Sun	10

df.drop(["A", "D"], axis=1)

# 	0	B	C
# 0	1.0	1.0	Mon
# 1	2.0	2.0	Tue
# 2	3.0	3.0	Wed
# 3	4.0	1.0	Thu
# 4	5.0	2.0	Fri
# 5	6.0	3.0	Sat
# 6	7.0	1.0	Sun

df.drop(columns="A")
# 或 df.drop(columns=["A"])
# 使用 columns 关键字参数时不再需要指定 axis

# 	0	B	C	D
# 0	1.0	1.0	Mon	10
# 1	2.0	2.0	Tue	10
# 2	3.0	3.0	Wed	10
# 3	4.0	1.0	Thu	10
# 4	5.0	2.0	Fri	10
# 5	6.0	3.0	Sat	10
# 6	7.0	1.0	Sun	10

Note: 上面使用 drop 的方法会返回一个新的 DataFrame , 如果想在原始的数据中修改, 则需要增加 inplace 参数, 并且无返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
df.drop("A", axis=1, inplace=True)
print(df)

# 	0	B	C	D
# 0	1.0	1.0	Mon	10
# 1	2.0	2.0	Tue	10
# 2	3.0	3.0	Wed	10
# 3	4.0	1.0	Thu	10
# 4	5.0	2.0	Fri	10
# 5	6.0	3.0	Sat	10
# 6	7.0	1.0	Sun	10

df.drop(columns="D", inplace=True)
print(df)

# 	0	B	C
# 0	1.0	1.0	Mon
# 1	2.0	2.0	Tue
# 2	3.0	3.0	Wed
# 3	4.0	1.0	Thu
# 4	5.0	2.0	Fri
# 5	6.0	3.0	Sat
# 6	7.0	1.0	Sun
  • 删除行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
df.drop(6, axis=0)
print(df)

# 	0	B	C
# 0	1.0	1.0	Mon
# 1	2.0	2.0	Tue
# 2	3.0	3.0	Wed
# 3	4.0	1.0	Thu
# 4	5.0	2.0	Fri
# 5	6.0	3.0	Sat

df.drop(index=6, inplace=True)
# 或 df.drop(index=[6], inplace=True)
print(df)

# 	0	B	C
# 0	1.0	1.0	Mon
# 1	2.0	2.0	Tue
# 2	3.0	3.0	Wed
# 3	4.0	1.0	Thu
# 4	5.0	2.0	Fri
# 5	6.0	3.0	Sat

3.3 修改

  • 使用索引修改
1
2
3
4
5
6
7
8
9
10
df[0] = [3., 2., 1., 3., 2., 1.]
print(df)

# 	0	B	C
# 0	3.0	1.0	Mon
# 1	2.0	2.0	Tue
# 2	1.0	3.0	Wed
# 3	3.0	1.0	Thu
# 4	2.0	2.0	Fri
# 5	1.0	3.0	Sat
  • 修改行/列/行列的方式和索引方式相同, 此处不再列举

4. DataFrame 常用方法

4.1 拼接多个 DataFrame

  • 拼接两个或多个 DataFrame 可以沿着纵向, 也可以沿着横向. 注意拼接后可能行/列名称不再唯一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# df1         df2        df3  
#   A B C       A B C      A B C
# 0 1 2 3     0 7 8 9    0 3 4 5
# 1 4 5 6     1 0 1 2    1 6 7 8

# 纵向拼接
D = pd.concat((A, B, C), axis=0)
print(D)

#   A B C
# 0 1 2 3
# 1 4 5 6
# 0 7 8 9
# 1 0 1 2
# 0 3 4 5
# 1 6 7 8

# 横向拼接
D = pd.concat((A, B, C), axis=1)
print(D)

#   A B C A B C A B C
# 0 1 2 3 7 8 9 3 4 5
# 1 4 5 6 0 1 2 6 7 8

4.2 基本运算符

  • 基本运算符只能应用于统一数据格式的DataFrame中, 并且运算符计算方式同元素的计算方式相同
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
print(df.loc[:2, "C"] + "ABC")

# 	C
# 0	MonABC
# 1	TueABC
# 2	WedABC

print(df.loc[:2, "C"] * 2)

# 	C
# 0	MonMon
# 1	TueTue
# 2	WedWed

print(df.loc[:2, "B"] * 2)

# 	C
# 0	2.0
# 1	3.0
# 2	4.0

Content