第1-3章

使用zip将两个序列配对组合成字典:

1
2
3
4
5
seq1 = ['foo','bar','baz']
seq2 = ['one','two','three']

x = dict(zip(seq1,seq2))
print(x) # {'foo': 'one', 'bar': 'two', 'baz': 'three'}

第四章

数组切片是原始数组的视图。这意味着数据不会被复制,视图上的任何修改都会直接反映到源数组上。
由于NumPy的设计目的是处理⼤数据,假如NumPy坚持要将数据复制来复制去的话会大量的性能和内存问题。


多维数组的索引问题

  • 切片索引:
    使用视图

  • 布尔索引:
    创建数据副本

  • 花式索引:

    创建数据副本

  • 数组转置:
    返回源数据的视图

    所谓的花式索引就是==利⽤整数数组进⾏索引==.

    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
    import numpy as np

    arr = np.empty((8,4))
    for i in range(8):
    arr[i] = i

    print(arr)
    # [[0. 0. 0. 0.]
    # [1. 1. 1. 1.]
    # [2. 2. 2. 2.]
    # [3. 3. 3. 3.]
    # [4. 4. 4. 4.]
    # [5. 5. 5. 5.]
    # [6. 6. 6. 6.]
    # [7. 7. 7. 7.]]

    print(arr[[4,3,0,6]])
    # [[4. 4. 4. 4.]
    # [3. 3. 3. 3.]
    # [0. 0. 0. 0.]
    # [6. 6. 6. 6.]]

    print(arr[[-1,-3,-5,-8]])
    # [[7. 7. 7. 7.]
    # [5. 5. 5. 5.]
    # [3. 3. 3. 3.]
    # [0. 0. 0. 0.]]

注意arr[1,2]arr[[1,2]]的区别:

  • arr[1,2]表示选取第一维度中索引值为1的数据,选区第二维度中索引值为2的数据
  • arr[[1,2]]表示选取第一维度中索引值为1和2的数据

简单来说,arr[1,2]是多维度选取,arr[[1,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
import numpy as np

arr = np.arange(32).reshape((8,4))
print(arr)
# [[ 0 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]]

print(arr[[1,5,7,2]])
# [[ 4 5 6 7]
# [20 21 22 23]
# [28 29 30 31]
# [ 8 9 10 11]]

print(arr[[1,5,7,2],[1,]])
# [ 5 21 29 9]

print(arr[[1,5,7,2],[0,3,1,2]])
# [ 4 23 29 10]

也就是说:
arr[[1,5,7,2],[0,3,1,2]]最终选出的是元素(1,0)、(5,3)、(7,1)和(2,2)。

所以,arr[[1,5,7,2],[1,]]最终选出的是元素(1,1)、(5,1)、(7,1)和(2,1)

注意z[[1,2]] [1]z[[1,2],1]的区别:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 花式索引跟切⽚不⼀样,它总是将数据复制到新数组中。
import numpy as np

z = np.arange(20).reshape((4,5))
print(z)
# [[ 0 1 2 3 4]
# [ 5 6 7 8 9]
# [10 11 12 13 14]
# [15 16 17 18 19]]

print(z[[1,2]])
# [[ 5 6 7 8 9]
# [10 11 12 13 14]]

# 花式索引是复制数据的
# 所以[1]会拿第二行数据
print(z[[1,2]] [1])
# [10 11 12 13 14]

# [[1,2],1]整体属于花式搜索
# 所以[,1]会拿第二列数据
print(z[[1,2],1])
# [ 6 11]

z[[1,2],1]是取完第一维度和取第二维度的值,z[[1,2]] [1]是取完第一维度后生成一个narray,对这个narray取第一维度的值


X.sum(axis=0)就是把第一个轴压缩掉.
简单来说,就是==把第一个轴同类的元素全部聚合成一个==

第五章

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
import pandas as pd
from pandas import Series,DataFrame

# 修改index
obj2 = Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
print(obj2)
# d 4
# b 7
# a -5
# c 3
# dtype: int64

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


print(obj2['a']) # -5
print(obj2.get('a')) # -5
print(obj2.get('XXX','hyl')) # hyl

print(obj2[['a','d','c']])
# a -5
# d 4
# c 3
# dtype: int64

['a','d','c']被称为索引列表

Series其实很像py里的字典.

如果只传⼊⼀个字典,则结果Series中的索引就是原字典的键(有序排列)


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

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

sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
states = ['California', 'Ohio', 'Oregon', 'Texas']
obj4 = Series(sdata, index=states)

# Series的name属性
obj4.name = 'population'
# Series.index的name属性
obj4.index.name = 'state'

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

DataFrame可以被看做由Series组成的字典.
也就是说,==DataFrame类似于一个字典,这个字典的键列名,字典的值就是Series对象==.


⽤标签的切⽚包含上限

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
25
26
27
28
import pandas as pd
import numpy as np

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

print(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

# 标签选的是列
print(data['one'])
# Ohio 0
# Colorado 4
# Utah 8
# New York 12
# Name: one, dtype: int32


# 切片选取的是行
print(data[:2])
# one two three four
# Ohio 0 1 2 3
# Colorado 4 5 6 7

⽤loc和iloc进⾏选取

⾏的标签索引:

  • loc:轴标签
  • iloc:整数索引
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
40
41
42
43
44
45
46
47
48
49
50
import pandas as pd
import numpy as np

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

print(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


# 选取单行多列
print(data.loc['Colorado', ['two', 'three']])
# two 5
# three 6
# Name: Colorado, dtype: int32


# 选取多行多列
print(data.loc[['Colorado','Ohio'], ['two', 'three']])
# two three
# Colorado 5 6
# Ohio 1 2


# 选取索引值为2的行,索引值为3,0,1的列
print(data.iloc[2, [3, 0, 1]])
# four 11
# one 8
# two 9
# Name: Utah, dtype: int32


# 选取索引值为2的行
print(data.iloc[2])
# one 8
# two 9
# three 10
# four 11
# Name: Utah, dtype: int32

# 选取索引值为1,2的行,索引值为3,0,1的列
print(data.iloc[[1, 2], [3, 0, 1]])
# four one two
# Colorado 7 4 5
# Utah 11 8 9

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
import pandas as pd
import numpy as np

people = ['hyl','dsz','gzr','czj']

ser = pd.Series(people,index=[1,2,3,4])
print(ser)
# 1 hyl
# 2 dsz
# 3 gzr
# 4 czj
# dtype: object

# 产生歧义,是选择标签索引的1还是位置索引的1
# 事实上选择的是标签的1
print(ser[1])
# hyl

# 为了避免歧义,当标签索引是整数时,索引为-1不可用,会发生KeyError
# print(ser[-1])


ser2 = pd.Series(np.arange(1,5))
print(ser2)
# 0 1
# 1 2
# 2 3
# 3 4
# dtype: int32


# 为了避免歧义,当没有标签索引时,索引为-1不可用,会发生KeyError
# print(ser2[-1])


# 当标签明确不为整数时,索引为-1可用
ser3 = pd.Series(np.arange(3.), index=['a', 'b', 'c'])
print(ser3[-1])
# 2.0

为了进⾏统⼀,==如果标签索引含有整数,数据选取总会使⽤标签。==


如果你希望匹配⾏且在列上⼴播,则必须使⽤算术运算⽅法

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
import pandas as pd
import numpy as np

frame = pd.DataFrame(np.arange(12.).reshape((4, 3)),
columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])

series3 = frame['d']

print(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

print(series3)
# Utah 1.0
# Ohio 4.0
# Texas 7.0
# Oregon 10.0
# Name: d, dtype: float64

# axis='index'或者axis=0
print(frame.sub(series3, axis='index'))
# b d e
# Utah -1.0 0.0 1.0
# Ohio -1.0 0.0 1.0
# Texas -1.0 0.0 1.0
# Oregon -1.0 0.0 1.0


print(frame.sub(series3, axis=1))
# Ohio Oregon Texas Utah b d e
# Utah NaN NaN NaN NaN NaN NaN NaN
# Ohio NaN NaN NaN NaN NaN NaN NaN
# Texas NaN NaN NaN NaN NaN NaN NaN
# Oregon NaN NaN NaN NaN NaN NaN NaN

applymap函数是DataFrame的元素级应用函数,
map函数就是Series的元素级应用函数


第六章

在读取CSV的时候,注意,如果没有使用header参数,那么第一行就会被视为列标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import pandas as pd
import numpy as np


# se2.csv没有标题行
print(pd.read_csv('ex2.csv'))
# a b c d hello
# 0 e f g h world
# 1 i j k l foo

# 为其自动添加默认的列名
print(pd.read_csv('ex2.csv',header=None))
# 0 1 2 3 4
# 0 a b c d hello
# 1 e f g h world
# 2 i j k l foo

# 添加自定义列名
names = ('c1 c2 c3 c4 c5').split()
print(pd.read_csv('ex2.csv',names=names))
# c1 c2 c3 c4 c5
# 0 a b c d hello
# 1 e f g h world
# 2 i j k l foo

第7章 数据清洗和准备

map, applymap apply的区别:

  • map:
    Series元素级函数映射
  • applymap:
    DataFrame元素级函数映射
  • apply:
    DataFrame轴级函数映射

第8章 数据规整:聚合、合并和重塑

不能通过传入字典的方式作为index来创建多层索引

1
2
3
4
5
6
7
8
import pandas as pd
import numpy as np


# 不能通过传入字典的方式作为index来创建多层索引
data = pd.Series(np.random.randn(9),
index={'a':[1,2,3],'b':[1,3],'c':[1,2],'d':[2,3]})
# ValueError: Length of passed values is 9, index implies 4

在进⾏列-列连接时,DataFrame对象中的索引会被丢弃。