《利用Python进行数据分析 第二版》 读书笔记 - 第四至六章

  • NumPy 基础:数组和矢量计算
  • pandas 入门
  • 数据加载、存储与文件格式

第4章 NumPy 基础:数组和矢量计算

4.1 NumPy的ndarray:一种多维数组对象

ndarray是一个通用的同构数据多维容器,也就是说,其中的所有元素必须是相同类型的。每个数组都有一个shape(一个表示各维度大小的元组)和一个dtype(一个用于说明数组数据类型的对象)

array函数接受一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的NumPy数组。

1
2
data1 = [6, 7.5, 8, 0, 1]
arr1 = np.array(data1)

嵌套序列(比如由一组等长列表组成的列表)将会被转换为一个多维数组。

由于NumPy关注的是数值计算,因此,如果没有特别指定,数据类型基本都是float64(浮点数)。

dtype(数据类型)对象将含有的ndarray一块内存解释为特定数据类型。

使用astype方法进行类型转换:

1
float_arr = arr.astype(np.float64)

可以用astype方法把数字字符串转换成数字。

1
2
3
4
In [64]: arr[5:8] = 12

In [65]: arr
Out[65]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])

当你将一个标量值赋值给一个切片时,该值会自动传播到整个选区。跟列表最重要的区别在于,数组切片是原始数组的引用。这意味着数据不会被复制,引用上的任何修改都会直接反映到源数组上。

高维数组的访问:

1
2
3
4
5
In [74]: arr2d[0][2]
Out[74]: 3

In [75]: arr2d[0, 2]
Out[75]: 3

高维数组切片的例子:arr2d[3][3]是二维数组,arr2d[:2, 1:]选取前两行、后两列,arr2d[:, :1]选取第一列,arr2d[:2, 2]选取第三列的前两行。

可以通过布尔数组选取某个轴,但是数组长度必须和轴的长度相等。

通过布尔型索引选取数组中的数据,将总是创建数据的副本。

传入一个用于指定顺序的整数列表或ndarray来以特定顺序选取某个轴。一次传入多个索引数组时返回的是一个一维数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
In [123]: arr
Out[123]:
array([[ 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]])

In [124]: arr[[1, 5, 7, 2], [0, 3, 1, 2]]
Out[124]: array([ 4, 23, 29, 10])

In [125]: arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]
Out[125]:
array([[ 4, 7, 5, 6],
[20, 23, 21, 22],
[28, 31, 29, 30],
[ 8, 11, 9, 10]])

T属性返回数组的转置,高维数组采用transpose方法,传入由轴编号组成的元组对这些轴进行转置。swapaxes传入一对轴的编号。

4.2 通用函数:快速的元素级数组函数

Ufuncs可以接受一个out可选参数,这样就能在数组原地进行操作:np.sqrt(arr, arr)

4.3 利用数组进行数据处理

numpy.where函数是三元表达式x if condition else y的矢量化版本。

根据cond中的值选取xarr和yarr的值:

1
np.where(cond, xarr, yarr)

np.where的第二个和第三个参数数组大小可以不相等,甚至可以是标量值。

meansum这类的函数可以接受一个axis选项参数,用于计算该轴向上的统计值, 最终结果是一个少一维的数组。

在多维数组中,累加函数(如cumsum)返回的是同样大小的数组,但是会根据每个低维的切片沿着标记轴计算部分聚类。

sum方法用于对布尔数组中的True计数,any方法检测是否存在Trueall方法判断是否全为True

sort方法可以排序,传入参数以按照某一个轴排序。

unqiue方法找出数组中的唯一值并返回已排序的结果。函数np.in1d用于测试一个数组中的值在另一个数组中的是否出现,返回一个布尔数组。

np.savenp.load用于读写磁盘数组数据。默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为.npy的文件中的。如果文件路径末尾没有扩展名.npy,则该扩展名会被自动加上。

1
2
np.save('some_array', arr)
np.load('some_array.npy')

通过np.savez可以将多个数组保存到一个未压缩文件中,将数组以关键字参数的形式传入即可:

1
In [216]: np.savez('array_archive.npz', a=arr, b=arr)

加载.npz文件时,你会得到一个类似字典的对象,该对象会对各个数组进行延迟加载:

1
2
3
4
In [217]: arch = np.load('array_archive.npz')

In [218]: arch['b']
Out[218]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

如果要将数据压缩,可以使用np.savez_compressed

4.5 线性代数

通过*对两个二维数组相乘得到的是 一个元素级的积,而不是一个矩阵点积。

通过x.dot(y)np.dot(x, y)x @ y实现矩阵乘法。

4.6 伪随机数生成

np.random.seed会更改全局种子,np.random.RandomState函数用给定种子创建一个新的随机数生成器:

1
2
3
In [245]: rng = np.random.RandomState(1234)

In [246]: rng.randn(10)

第5章 pandas 入门

5.1 pandas的数据结构介绍

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

1
2
3
4
5
6
7
8
9
In [11]: obj = pd.Series([4, 7, -5, 3])

In [12]: obj
Out[12]:
0 4
1 7
2 -5
3 3
dtype: int64

Series的字符串表现形式为:索引在左边,值在右边。通过Seriesvaluesindex属性获取其数组表示形式和索引对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
In [15]: obj2 = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])

In [16]: obj2
Out[16]:
d 4
b 7
a -5
c 3
dtype: int64

In [17]: obj2.index
Out[17]: Index(['d', 'b', 'a', 'c'], dtype='object')

In [18]: obj2['a']
Out[18]: -5

In [19]: obj2['d'] = 6

In [20]: obj2[['c', 'a', 'd']]
Out[20]:
c 3
a -5
d 6
dtype: int64

使用NumPy函数或类似NumPy的运算(如根据布尔型数组进行过滤、标量乘法、应用数学函数等)都会保留索引值的链接。还可以将Series看成是一个定长的有序字典,因为它是索引值到数据值的一个映射。如果数据被存放在一个Python字典中,也可以直接通过这个字典来创建Series

通过传入排好序的键的序列以改变顺序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
In [26]: sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000 , 'Utah': 5000}

In [27]: obj3 = pd.Series(sdata)

In [28]: obj3
Out[28]:
Ohio 35000
Texas 71000
Oregon 16000
Utah 5000
dtype: int64

In [29]: states = ['California', 'Ohio', 'Oregon', 'Texas']

In [30]: obj4 = pd.Series(sdata, index=states)

In [31]: obj4
Out[31]:
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64

'California'没有对应的值,用NaN表示缺失值;'Utah'没有出现。

isnullnotnull函数或者Seriesisnull方法判断是否缺失:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
In [32]: pd.isnull(obj4)
Out[32]:
California True
Ohio False
Oregon False
Texas False
dtype: bool

In [34]: obj4.notnull()
Out[34]:
California False
Ohio True
Oregon True
Texas True
dtype: bool

根据运算的索引标签自动对齐数据:

1
2
3
4
5
6
7
8
In [37]: obj3 + obj4
Out[37]:
California NaN
Ohio 70000.0
Oregon 32000.0
Texas 142000.0
Utah NaN
dtype: float64

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

Series的索引可以通过赋值的方式就地修改:

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

DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典(共用同一个索引)。

直接传入一个由等长列表或NumPy数组组成的字典来创建DataFrame

1
2
3
4
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)
1
2
3
4
5
6
7
8
9
In [45]: frame
Out[45]:
state year pop
0 Ohio 2000 1.5
1 Ohio 2001 1.7
2 Ohio 2002 3.6
3 Nevada 2001 2.4
4 Nevada 2002 2.9
5 Nevada 2003 3.2

对于特别大的DataFramehead方法会选取前五行。如果指定了列序列,则DataFrame的列就会按照指定顺序进行排列:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
In [48]: frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
...: index=['one', 'two', 'three', 'four',
...: 'five', 'six'])
...:

In [49]: frame2
Out[49]:
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 NaN
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 NaN
five 2002 Nevada 2.9 NaN
six 2003 Nevada 3.2 NaN

In [50]: frame2.columns
Out[50]: Index(['year', 'state', 'pop', 'debt'], dtype='object')

通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series

1
2
frame2['state']
frame2.year

返回的Series拥有原DataFrame相同的索引,且其name属性也已经被相应地设置好了。

通过loc属性获取行:

1
2
3
4
5
6
7
In [53]: frame2.loc['three']
Out[53]:
year 2002
state Ohio
pop 3.6
debt NaN
Name: three, dtype: object

通过赋值修改列:

1
2
3
frame2['debt'] = 16.5
frame2['debt'] = np.arange(6.)
frame2['debt'] = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four' , 'five'])

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

关键字del用于删除列。

如果嵌套字典传给DataFrame,pandas就会被解释为:外层字典的键作为列,内层键则作为行索引:

1
2
3
4
5
6
7
8
9
10
11
In [65]: pop = {'Nevada': {2001: 2.4, 2002: 2.9},
...: 'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}

In [66]: frame3 = pd.DataFrame(pop)

In [67]: frame3
Out[67]:
Nevada Ohio
2001 2.4 1.7
2002 2.9 3.6
2000 NaN 1.5

内层字典的键会被合并、排序以形成最终的索引。如果明确指定了索引,则不会这样:

1
pd.DataFrame(pop, index=[2001, 2002, 2003])

DataFrameindexcolumns也有name属性。

values属性会以二维ndarray的形式返回DataFrame中的数据。如果DataFrame各列的数据类型不同,则值数组的dtype就会选用能兼容所有列的数据类型。

构建SeriesDataFrame时,所用到的任何数组或其他序列的标签都会被转换成一个Index对象。Index对象是不可变的。Index的功能也类似一个固定大小的集合,但是可以包含重复的标签,选择重复的标签,会显示所有的结果。

5.2 基本功能

Seriesreindex方法将会根据新索引进行重排。如果某个索引值当前不存在,就引入缺失值。method选项实现插值,例如,使用ffill可以实现前向值填充。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
In [95]: obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])

In [96]: obj3
Out[96]:
0 blue
2 purple
4 yellow
dtype: object

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

重新索引列:

1
frame.reindex(columns=states)

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

默认删除行,通过制定axis删除列:

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
In [110]: data = pd.DataFrame(np.arange(16).reshape((4, 4)),
...: index=['Ohio', 'Colorado', 'Utah', 'New York'],
...: columns=['one', 'two', 'three', 'four'])

In [111]: data
Out[111]:
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

In [112]: data.drop(['Colorado', 'Ohio'])
Out[112]:
one two three four
Utah 8 9 10 11
New York 12 13 14 15

In [113]: data.drop('two', axis=1)
Out[113]:
one three four
Ohio 0 2 3
Colorado 4 6 7
Utah 8 10 11
New York 12 14 15

In [114]: data.drop(['two', 'four'], axis='columns')
Out[114]:
one three
Ohio 0 2
Colorado 4 6
Utah 8 10
New York 12 14

选项inplace=True使得就地删除。

既可以使用数字索引,也可以使用index

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
In [117]: obj = pd.Series(np.arange(4.), index=['a', 'b', 'c', 'd'])

In [118]: obj
Out[118]:
a 0.0
b 1.0
c 2.0
d 3.0
dtype: float64

In [119]: obj['b']
Out[119]: 1.0

In [120]: obj[1]
Out[120]: 1.0

In [124]: obj[obj < 2]
Out[124]:
a 0.0
b 1.0
dtype: float64

In [126]: obj['b':'c'] = 5

In [127]: obj
Out[127]:
a 0.0
b 5.0
c 5.0
d 3.0
dtype: float64

利用标签的切片运算是一个闭区间。

用一个值或序列对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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
In [128]: data = pd.DataFrame(np.arange(16).reshape((4, 4)),
...: index=['Ohio', 'Colorado', 'Utah', 'New York'],
...: columns=['one', 'two', 'three', 'four'])

In [131]: data[['three', 'one']]
Out[131]:
three one
Ohio 2 0
Colorado 6 4
Utah 10 8
New York 14 12

In [132]: data[:2]
Out[132]:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7

In [133]: data[data['three'] > 5]
Out[133]:
one two three four
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15

In [134]: data < 5
Out[134]:
one two three four
Ohio True True True True
Colorado True False False False
Utah False False False False
New York False False False False

In [135]: data[data < 5] = 0

In [136]: data
Out[136]:
one two three four
Ohio 0 0 0 0
Colorado 0 5 6 7
Utah 8 9 10 11
New York 12 13 14 15

如果轴索引含有整数,数据选取总会使用标签。为了更准确,请使用loc(标签)或iloc(整数)

将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集。自动的数据对齐操作在不重叠的索引处引入了NaN值。缺失值会在算术运算过程中传播。

当一个对象中某个轴标签在另一 个对象中找不到时填充一个特殊值:

1
df1.add(df2, fill_value=0)

reindex也可以指定填充值。

DataFrameSeries之间的算术运算会将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
In [179]: frame = pd.DataFrame(np.arange(12.).reshape((4, 3)),
...: columns=list('bde'),
...: index=['Utah', 'Ohio', 'Texas', 'Oregon'])

In [180]: series = frame.iloc[0]

In [181]: frame
Out[181]:
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

In [182]: series
Out[182]:
b 0.0
d 1.0
e 2.0
Name: Utah, dtype: float64

In [183]: frame - series
Out[183]:
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的列或Series的索引中找不到,则参与运算的两个对象就会被重新索引以形成并集

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
In [186]: series3 = frame['d']

In [188]: series3
Out[188]:
Utah 1.0
Ohio 4.0
Texas 7.0
Oregon 10.0
Name: d, dtype: float64

In [189]: frame.sub(series3, axis='index')
Out[189]:
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

NumPy的ufuncs也可用于操作pandas对象。

DataFrameapply方法实现将函数应用到由各列或行所形成的一维数组上:

1
2
3
4
5
6
7
8
9
10
11
In [190]: frame = pd.DataFrame(np.random.randn(4, 3), columns=list('bde'),
...: index=['Utah', 'Ohio', 'Texas', 'Oregon'])

In [193]: f = lambda x: x.max() - x.min()

In [194]: frame.apply(f)
Out[194]:
b 1.379224
d 2.469903
e 2.369424
dtype: float64

传递axis='columns'使得函数在每行执行。

应用元素级的函数,使用DataFrameapplymap方法、Seriesmap方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
In [198]: format = lambda x: '%.2f' % x

In [199]: frame.applymap(format)
Out[199]:
b d e
Utah -1.06 -0.73 -0.42
Ohio -0.24 1.74 -1.11
Texas -0.80 0.51 1.10
Oregon -1.61 1.10 1.26

In [200]: frame['e'].map(format)
Out[200]:
Utah -0.42
Ohio -1.11
Texas 1.10
Oregon 1.26
Name: e, dtype: object

对行或列索引进行排序(按字典顺序),可使用sort_index方法,它将返回一个已排序的新对象。默认对行排序,axis=1选项使得对列排序;默认按升序排序,ascending=False选项使得按降序排序。

1
2
3
4
5
6
7
8
9
In [201]: obj = pd.Series(range(4), index=['d', 'a', 'b', 'c'])

In [202]: obj.sort_index()
Out[202]:
a 1
b 2
c 3
d 0
dtype: int64

按值对Series进行排序,使用sort_values方法。缺失值放到末尾。对DataFrame排序,传入列的名字,或者传入列的名字的列表(在前的优先级高)。

1
2
3
4
5
6
7
8
9
In [207]: obj = pd.Series([4, 7, -3, 2])

In [208]: obj.sort_values()
Out[208]:
2 -3
3 2
0 4
1 7
dtype: int64

rank方法给出排名,对于相同元素来说,默认取所有排名的平均值。ascending=False选项使得按降序排名。对于DataFrame,可以使用axis选项。

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
In [215]: obj = pd.Series([7, -5, 7, 4, 2, 0, 4])

In [216]: obj.rank()
Out[216]:
0 6.5
1 1.0
2 6.5
3 4.5
4 3.0
5 2.0
6 4.5
dtype: float64

In [219]: frame = pd.DataFrame({'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1],
...: 'c': [-2, 5, 8, -2.5]})

In [220]: frame
Out[220]:
b a c
0 4.3 0 -2.0
1 7.0 1 5.0
2 -3.0 0 8.0
3 2.0 1 -2.5

In [221]: frame.rank(axis='columns')
Out[221]:
b a c
0 3.0 2.0 1.0
1 3.0 1.0 2.0
2 1.0 2.0 3.0
3 3.0 2.0 1.0

以下是可用的method选项:

索引的is_unique属性可以告诉你它的值是否是唯一的。

如果选取Series的某个索引对应多个值,则返回一个Series;而对应单个值的,则返回一个标量值。对于DataFrame,如果选取某个索引对应多个值,则返回一个DataFrame

5.3 汇总和计算描述统计

Seriescorr方法用于计算两个Series中重叠的、非NA的、按索引对齐的值的相关系数。与此类似,cov用于计算协方差。DataFramecorrcov方法将以DataFrame的形式分别返回完整的相关系数或协方差矩阵。

利用DataFramecorrwith方法,你可以计算其列或行跟另一个SeriesDataFrame之间的相关系数。传入一个Series将会返回一个相关系数值Series(针对各列进行计算)。传入一个DataFrame则会计算按列名配对的相关系数。传入axis='columns'即可按行进行计算。

unique方法得到Series中的唯一值数组。value_counts方法用于计算一个Series中各值出现的频率。结果Series是按值频率降序排列的。value_counts还是一个顶级pandas方法,可用于任何数组或序列:

1
2
3
4
5
6
7
8
9
In [251]: obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'b', 'b', 'c' , 'c'])

In [255]: pd.value_counts(obj.values, sort=False)
Out[255]:
a 3
d 1
b 2
c 3
dtype: int64

isin方法返回一个布尔型Series,用于判断矢量化集合的成员资格:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
In [257]: mask = obj.isin(['b', 'c'])

In [258]: mask
Out[258]:
0 True
1 False
2 False
3 False
4 False
5 True
6 True
7 True
8 True
dtype: bool

In [259]: obj[mask]
Out[259]:
0 c
5 b
6 b
7 c
8 c
dtype: object

Index.get_indexer方法给你一个索引数组,从可能包含重复值的数组到另一个不包含重复值的数组。

1
2
3
4
5
6
In [260]: to_match = pd.Series(['c', 'a', 'b', 'b', 'c', 'a'])

In [261]: unique_vals = pd.Series(['c', 'b', 'a'])

In [262]: pd.Index(unique_vals).get_indexer(to_match)
Out[262]: array([0, 2, 1, 1, 0, 2])

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
In [263]: data = pd.DataFrame({'Qu1': [1, 3, 4, 3, 4],
...: 'Qu2': [2, 3, 1, 2, 3],
...: 'Qu3': [1, 5, 2, 4, 4]})

In [264]: data
Out[264]:
Qu1 Qu2 Qu3
0 1 2 1
1 3 3 5
2 4 1 2
3 3 2 4
4 4 3 4

In [265]: result = data.apply(pd.value_counts).fillna(0)

In [266]: result
Out[266]:
Qu1 Qu2 Qu3
1 1.0 1.0 1.0
2 0.0 2.0 1.0
3 2.0 2.0 0.0
4 2.0 0.0 2.0
5 0.0 0.0 1.0

第6章 数据加载、存储与文件格式

6.1 读写文本格式的数据

读入.csv:

1
2
df = pd.read_csv('examples/ex1.csv')
pd.read_table('examples/ex1.csv', sep=',')

没有标题行:

1
2
pd.read_csv('examples/ex2.csv', header=None)
pd.read_csv('examples/ex2.csv', names=['a', 'b', 'c', 'd', 'message'])

指定索引:

1
2
names = ['a', 'b', 'c', 'd', 'message']
pd.read_csv('examples/ex2.csv', names=names, index_col='message')

层次化索引:

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
In [17]: !cat examples/csv_mindex.csv
key1,key2,value1,value2
one,a,1,2
one,b,3,4
one,c,5,6
one,d,7,8
two,a,9,10
two,b,11,12
two,c,13,14
two,d,15,16

In [18]: parsed = pd.read_csv('examples/csv_mindex.csv',
....: index_col=['key1', 'key2'])

In [19]: parsed
Out[19]:
value1 value2
key1 key2
one a 1 2
b 3 4
c 5 6
d 7 8
two a 9 10
b 11 12
c 13 14
d 15 16

对于不规整的表格,使用正则表达式:

1
2
3
4
5
6
7
8
9
In [20]: list(open('examples/ex3.txt'))
Out[20]:
[' A B C\n',
'aaa -0.264438 -1.026059 -0.619500\n',
'bbb 0.927272 0.302904 -0.032399\n',
'ccc -0.264273 -0.386314 -0.217601\n',
'ddd -0.871858 -0.348382 1.100491\n']

In [21]: result = pd.read_table('examples/ex3.txt', sep='\s+')

跳过第一行、第三行和第四行:

1
pd.read_csv('examples/ex4.csv', skiprows=[0, 2, 3])

pandas能够自动识别缺失数据(空字符串或者标记值比如NANULL

用一个列表或者集合的字符串表示标记值,各个列可以使用不同的标记值:

1
2
3
4
5
6
7
8
9
10
In [29]: result = pd.read_csv('examples/ex5.csv', na_values=['NULL'])

In [31]: sentinels = {'message': ['foo', 'NA'], 'something': ['two']}

In [32]: pd.read_csv('examples/ex5.csv', na_values=sentinels)
Out[32]:
something a b c d message
0 one 1 2 3.0 4 NaN
1 NaN 5 6 NaN 8 world
2 three 9 10 11.0 12 NaN

设置最大显示行数:

1
pd.options.display.max_rows = 10

nrows选项指定读取多少行。

逐块读取:

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
In [37]: chunker = pd.read_csv('examples/ex6.csv', chunksize=1000)

In [38]: chunker
Out[38]: <pandas.io.parsers.TextFileReader at 0x7f87a2627d90>

In [39]: chunker = pd.read_csv('examples/ex6.csv', chunksize=1000)
...:
...: tot = pd.Series([])
...: for piece in chunker:
...: tot = tot.add(piece['key'].value_counts(), fill_value=0)
...:
...: tot = tot.sort_values(ascending=False)

In [40]: tot[:10]
Out[40]:
E 368.0
X 364.0
L 346.0
O 343.0
Q 340.0
M 338.0
J 337.0
F 335.0
K 334.0
H 330.0
dtype: float64

使用to_csv方法输出到.csv;指定分隔符;指定缺失值的标记;禁用行列的标签;写出部分列:

1
2
3
4
5
data.to_csv('examples/out.csv')
data.to_csv(sys.stdout, sep='|')
data.to_csv(sys.stdout, na_rep='NULL')
data.to_csv(sys.stdout, index=False, header=False)
data.to_csv(sys.stdout, index=False, columns=['a', 'b', 'c'])

Python内置的csv模块:

1
2
3
import csv
f = open('examples/ex7.csv')
reader = csv.reader(f)

对这个reader进行迭代将会为每行产生一个元组(并移除了所有的引号)。

1
2
3
4
5
6
7
8
9
10
In [57]: with open('examples/ex7.csv') as f:
...: lines = list(csv.reader(f))
...:

In [58]: header, values = lines[0], lines[1:]

In [59]: data_dict = {h: v for h, v in zip(header, zip(*values))}

In [60]: data_dict
Out[60]: {'a': ('1', '1'), 'b': ('2', '2'), 'c': ('3', '3')}

定义csv.Dialect的一个子类即可定义出新格式(如专门的分隔符、字符串引用约定、行结束符等):

1
2
3
4
5
6
class my_dialect(csv.Dialect):
lineterminator = '\n'
delimiter = ';'
quotechar = '"'
quoting = csv.QUOTE_MINIMAL
reader = csv.reader(f, dialect=my_dialect)

或者通过参数传递:

1
reader = csv.reader(f, delimiter='|')

要手工输出分隔符文件,使用csv.writer

1
2
3
4
5
6
with open('mydata.csv', 'w') as f:
writer = csv.writer(f, dialect=my_dialect)
writer.writerow(('one', 'two', 'three'))
writer.writerow(('1', '2', '3'))
writer.writerow(('4', '5', '6'))
writer.writerow(('7', '8', '9'))

通过json.loads即可将JSON字符串转换成Python形式;json.dumps则将Python对象转换成JSON格式:

1
2
3
import json
result = json.loads(obj)
asjson = json.dumps(result)

通过传入字典的列表把JSON对象转化成DataFrame

pandas.read_json的默认选项假设JSON数组中的每个对象是表格中的一行:

1
2
3
4
5
6
7
8
9
10
11
12
13
In [68]: !cat examples/example.json
[{"a": 1, "b": 2, "c": 3},
{"a": 4, "b": 5, "c": 6},
{"a": 7, "b": 8, "c": 9}]

In [69]: data = pd.read_json('examples/example.json')

In [70]: data
Out[70]:
a b c
0 1 2 3
1 4 5 6
2 7 8 9

将数据从pandas输出到JSON,可以使用to_json方法。

pandas.read_html将HTML文件中的表格解析为DataFrame对象。

6.2 二进制数据格式

pandas对象都有一个用于将数据以pickle格式保存到磁盘上的to_pickle方法;使用pandas.read_pickle读取被pickle化的数据:

1
2
frame.to_pickle('examples/frame_pickle')
pd.read_pickle('examples/frame_pickle')

HDF5是一种存储大规模科学数组数据的非常好的文件格式。它可以被作为C标准库,带有许多语言的接口,如Java、Python和MATLAB等。

1
2
3
4
5
6
7
In [92]: frame = pd.DataFrame({'a': np.random.randn(100)})

In [93]: store = pd.HDFStore('mydata.h5')

In [94]: store['obj1'] = frame

In [95]: store['obj1_col'] = frame['a']

pandas的ExcelFile类或pandas.read_excel函数支持读取存储在Excel 2003(或更高版本)中的表格型数据。

6.3 Web APIs交互

requests扩展库

6.4 数据库交互

《利用Python进行数据分析 第二版》 读书笔记 - 第四至六章

https://blog.xqmmcqs.com/《利用Python进行数据分析 第二版》读书笔记 - 第四至六章/

作者

xqmmcqs

发布于

2021-01-09

更新于

2021-02-23

许可协议

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×