文章目录
《Python数据科学手册》读书笔记
安装并使用Pandas
import numpy as np
# 检查pandas的版本号
import pandas as pd
pd.__version__
'0.23.4'
pd?
Pandas对象简介
如果从底层视角观察Pandas,可以把它们看成增强版的Numpy结构化数组,行列都不再是简单的整数索引,还可以带上标签。
先来看看Pandas三个基本的数据结构:
- Series
- DataFrame
- Index
Pandas的Series对象
Pandas的Series对象是一个带索引数据构成的一维数组,可以用一个数组创建Series对象
data = pd.Series([0.25, 0.5, 0.75, 1.0])
data
0 0.25
1 0.50
2 0.75
3 1.00
dtype: float64
我们可以通过values属性和index属性获取数据。values属性返回的结果和Numpy数组类似
data.values
array([0.25, 0.5 , 0.75, 1. ])
index属性返回结果是一个类型为pd.Index的类数组对象
data.index
RangeIndex(start=0, stop=4, step=1)
data[1]
0.5
data[1:3]
1 0.50
2 0.75
dtype: float64
可以看出Pandas的Series对象比它模仿的一维Numpy数组更加通用
Series是广义的Numpy数组
Series对象和Numpy数组基本可以等价代换,但两者间的本质差异其实是索引:
- Numpy数组通过隐式定义的整数索引获取数值
- Series对象是一种显示定义的索引与数值关联
显示定义的索引让Series对象有了更加强大的能力。
例如:索引不再仅仅是整数,还可以是任意想要的类型
data = pd.Series([0.25, 0.5, 0.75, 1.0],
index=['a', 'b', 'c', 'd'])
data
a 0.25
b 0.50
c 0.75
d 1.00
dtype: float64
# 获取索引b的数值
data['b']
0.5
也可以使用不连续或者不按顺序的索引
data = pd.Series([0.25, 0.5, 0.75, 1.0],
index=[2, 5, 3, 7])
data
2 0.25
5 0.50
3 0.75
7 1.00
dtype: float64
Series是特殊的字典
字典是将任意键映射到一组任意值的结构,而Series对象是将类型化键映射到一组类型化值的结构。这种类型很重要:就像NumPy数组背后的特定类型编译代码使它在某些操作上比Python列表更有效一样,Series对象的类型信息使它在某些操作上比Python字典更有效。
可以直接用Python字典创建一个Series对象,让Series对象与字典进行类比
population_dict = {'California': 38332521,
'Texas': 26448193,
'New York': 19651127,
'Florida': 19552860,
'Illinois': 12882135}
population = pd.Series(population_dict)
population
California 38332521
Texas 26448193
New York 19651127
Florida 19552860
Illinois 12882135
dtype: int64
用字典创建Series对象时,其索引默认按照顺序排列
population['California']
38332521
和字典不同,Series对象还支持数组形式的操作
# 切片操作
population['California':'Illinois']
California 38332521
Texas 26448193
New York 19651127
Florida 19552860
Illinois 12882135
dtype: int64
创建Series对象
- pd.Series(data, index=index)
其中index是一个可选参数,data参数支持多种数据类型
data可以是列表或者是Numpy数组,这时index默认值为整数数列:
pd.Series([2, 4, 6])
0 2
1 4
2 6
dtype: int64
data也可以是标量,这样创建Series对象时会重复填充到每个索引上:
pd.Series(5, index=[100, 200, 300])
100 5
200 5
300 5
dtype: int64
data还可以是一个字典,index默认是排序的字典键:
pd.Series({2:'a', 1:'b', 3:'c'})
2 a
1 b
3 c
dtype: object
每一种形式都可以通过显示指定索引筛选所需要的结果
# Series对象只会保留显示定义的键值对
pd.Series({2:'a', 1:'b', 3:'c'}, index=[3, 2])
3 c
2 a
dtype: object
# 当索引值长度大于data长度,自动用NaN填充
pd.Series({2:"a",1:'b',3:"c"},index={1,2,3,4})
1 b
2 a
3 c
4 NaN
dtype: object
Pandas的DataFrame对象
Pandas的另一个基础数据结构是DataFrame。和之前介绍的Series一样,DataFrame既可以作为一个通用型Numpy数组,也可以看做特殊的Python字典。
DataFrame是广义的Numpy数组
如果将Series 类比为带灵活索引的一维数组,那么DataFrame 就可以看作是一种既有灵活的行索引,又有灵活列索引的二维数组。就像你可以把二维数组看成是有序排列的一维数组一样,你也可以把DataFrame 看成是有序排列的若干Series 对象。这里的“排列”指的是它们拥有共同的索引。
area_dict = {'California': 423967, 'Texas': 695662, 'New York': 141297,
'Florida': 170312, 'Illinois': 149995}
area = pd.Series(area_dict)
area
California 423967
Texas 695662
New York 141297
Florida 170312
Illinois 149995
dtype: int64
再结合之前创建的population的Series对象,用一个字典创建一个包含以上信息的二维对象
states = pd.DataFrame({'population': population,
'area': area})
states
population | area | |
---|---|---|
California | 38332521 | 423967 |
Texas | 26448193 | 695662 |
New York | 19651127 | 141297 |
Florida | 19552860 | 170312 |
Illinois | 12882135 | 149995 |
# 用index属性获取行索引标签
states.index
Index(['California', 'Texas', 'New York', 'Florida', 'Illinois'], dtype='object')
# 用columns属性获取列索引标签
states.columns
Index(['population', 'area'], dtype='object')
因此,DataFrame 可以看作一种通用的NumPy 二维数组,它的行与列都可以通过索引获取。
DataFrame是特殊的字典
与Series 类似,我们也可以把DataFrame 看成一种特殊的字典。字典是一个键映射一个值,而DataFrame 是一列映射一个Series 的数据。例如,通过’area’ 的列属性可以返回
包含面积数据的Series 对象:
# 面积数据
states['area']
California 423967
Texas 695662
New York 141297
Florida 170312
Illinois 149995
Name: area, dtype: int64
创建DataFrame对象
- 通过单个Series对象创建
给一个Series对象作为data,给定列名columns
pd.DataFrame(population, columns=['population'])
population | |
---|---|
California | 38332521 |
Texas | 26448193 |
New York | 19651127 |
Florida | 19552860 |
Illinois | 12882135 |
- 任何元素是字典的列表都可以变成DataFrame。用一个简单的列表综合来创建一些数据:
data = [{'a': i, 'b': 2 * i}
for i in range(3)]
pd.DataFrame(data)
a | b | |
---|---|---|
0 | 0 | 0 |
1 | 1 | 2 |
2 | 2 | 4 |
即使字典中有些键不存在,Pandas 也会用缺失值NaN(不是数字,not a number)来表示:
pd.DataFrame([{'a': 1, 'b': 2}, {'b': 3, 'c': 4}])
a | b | c | |
---|---|---|---|
0 | 1.0 | 2 | NaN |
1 | NaN | 3 | 4.0 |
- 通过Series对象字典创建
用一个字典创建,字典的value值为Series对象
pd.DataFrame({'population': population,
'area': area})
population | area | |
---|---|---|
California | 38332521 | 423967 |
Texas | 26448193 | 695662 |
New York | 19651127 | 141297 |
Florida | 19552860 | 170312 |
Illinois | 12882135 | 149995 |
- 通过NumPy二维数组创建
假如有一个二维数组,就可以创建一个可以指定行列索引值的DataFrame。如果不指定行列索引值,那么行列默认都是整数索引值:(本质是给一个多维Series对象,给定行索引index,给定列索引columus,默认为None)
pd.DataFrame(np.random.rand(3, 2),
columns=['foo', 'bar'],
index=['a', 'b', 'c'])
foo | bar | |
---|---|---|
a | 0.611537 | 0.795093 |
b | 0.789713 | 0.050002 |
c | 0.209812 | 0.051797 |
Pandas的Index对象
Series 和DataFrame 对象都使用便于引用和调整的显式索引。Pandas 的
Index 对象是一个很有趣的数据结构,可以将它看作是一个不可变数组或有序集合
# 使用一个简单的列表创建Index对象
ind = pd.Index([2, 3, 5, 7, 11])
ind
Int64Index([2, 3, 5, 7, 11], dtype='int64')
将Index看作不可变数组
Index 对象的许多操作都像数组。例如,可以通过标准Python 的取值方法获取数值,也可以通过切片获取数值:
ind[1]
3
ind[::2]
Int64Index([2, 5, 11], dtype='int64')
Index对象有许多和Numpy数组相似的属性
print(ind.size, ind.shape, ind.ndim, ind.dtype)
5 (5,) 1 int64
Index对象的索引是不可逆的,也就是说不能通过赋值的方法进行调整
ind[1] = 0
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-49-906a9fa1424c> in <module>()
----> 1 ind[1] = 0
C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\indexes\base.py in __setitem__(self, key, value)
2063
2064 def __setitem__(self, key, value):
-> 2065 raise TypeError("Index does not support mutable operations")
2066
2067 def __getitem__(self, key):
TypeError: Index does not support mutable operations
Index 对象的不可变特征使得多个DataFrame 和数组之间进行索引共享时更加安全,尤其是可以避免因修改索引时粗心大意而导致的副作用。
将Index看作有序集合
Index对象可以求交集、并集
indA = pd.Index([1, 3, 5, 7, 9])
indB = pd.Index([2, 3, 5, 7, 11])
indA & indB # 交集
Int64Index([3, 5, 7], dtype='int64')
indA | indB # 并集
Int64Index([1, 2, 3, 5, 7, 9, 11], dtype='int64')
indA ^ indB # 异或
Int64Index([1, 2, 9, 11], dtype='int64')
这些操作还可以通过调用对象方法来实现,例如 indA.intersection(indB)
来源:CSDN
作者:少年吉
链接:https://blog.csdn.net/weixin_41503009/article/details/104184831