pandas建造在NumPy之上,它使得以NumPy为中心的应用很容易使用。pandas数据结构主要有:Series、DataFrame。首先引入模块:
Series
Series是一个类似一维数组的对象,包含:
- values:任何NumPy的数据类型组成的数组
- index:与数组关联的标签
可以分别的通过它的 values 和 index 属性来获取Series的数组表示和索引对象
创建
创建可以有几种方式:
- 由数组(list/tuple)创建:
- 不指定索引:默认索引为整数0到 N-1(N为数组长度)
- 指定索引:index参数指定索引
- 由dict创建:key–>index,value–>values
- 由Series创建:指定index时,只提取原Series的index对应的值,没有的为NAN12345678910111213# 不指定索引obj = pd.Series([4, 7, -5, 3])print(obj.values, obj.index, obj, sep='\n')# 指定索引obj2 = pd.Series((4, 7, -5, 3), index=['d', 'b', 'a', 'c'])print(obj2.values, obj2.index, obj2, sep='\n')# 字典创建sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}obj3 = pd.Series(sdata)# Series创建states = ['California', 'Ohio', 'Oregon', 'Texas']obj4 = pd.Series(sdata, index=states)print(obj3, obj4, sep='\n')
修改
增
与dict新增属性一样
删
drop 方法将会返回一个新的对象并从坐标轴中删除指定的一个或多个值,inplace参数决定是否输出到原df
改
分为值修改和索引更改
说明:reindex()跟直接修改index属性的对比在重新索引部分会讲到
查询
- NumPy查询,将会保持索引和值间的关联
- 下标取数据
- 布尔数组过滤
- 纯量乘法
- 使用数学函数
- 与NumPy不同的查询,可以使用索引里的值来选择一个单一值或一个值集1234print(obj2['a', 'c'])print(obj2[:2])print(obj2[obj2 > 0], obj2 * 2, np.exp(obj2))print('b' in obj2, 'e' in obj2, sep='\n')
其他
算术运算:会自动对齐不同索引的数据
name属性:Series对象本身和它的索引都有一个name 属性,它和pandas的其它一些关键功能整合在一起
DataFrame
DataFrame类似于数据库中的表,不过DataFrame不仅仅限制于2维,可以创建多维数据表。DataFrame既有行索引,也有列索引,可以看做是Series组成的字典,每个Series看做DataFrame的一个列。
创建
由字典创建
可选参数:
- columns:可以决定列的顺序,没有的会以NaN补充
- index:索引值,默认值为0到N-11234567891011data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],'year': [2000, 2001, 2002, 2001, 2002],'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}frame = pd.DataFrame(data)print(frame)frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop'])print(frame2)frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'])print(frame2)frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'], index=['one', 'two', 'three', 'four', 'five'])print(frame2)
numpy数组创建
等长的numpy数组
嵌套字典的字典
它的外部键会被解释为列索引,内部键会被解释为行索引
其他
由其他df创建:
可能的传递到DataFrame的构造器:
| 类型 | 说明 |
|---|---|
| 二维ndarray | 一个数据矩阵,有可选的行标和列标 |
| 数组,列表或元组的字典 | 每一个序列成为DataFrame中的一列。所有的序列必须有相同的长度。 |
| NumPy的结构/记录数组 | 和“数组字典”一样处理 |
| Series的字典 | 每一个值成为一列。如果没有明显的传递索引,将结合每一个Series的索引来形成结果的行索引。 |
| 字典的字典 | 每一个内部的字典成为一列。和“Series的字典”一样,结合键值来形成行索引。 |
| 字典或Series的列表 | 每一项成为DataFrame中的一列。结合字典键或Series索引形成DataFrame的列标。 |
| 列表或元组的列表 | 和“二维ndarray”一样处理 |
| 另一个DataFrame | DataFrame的索引将被使用,除非传递另外一个 |
| NumPy伪装数组(MaskedArray) | 除了蒙蔽值在DataFrame中成为NA/丢失数据之外,其它的和“二维ndarray”一样 |
修改
增
增加新的一列,跟dict操作一样
删
del:删除一列,跟dict一样
dorp():删除行或者列
- axis:删除轴,跟numpy一样,axis=0表示行,axis=1表示列
- inplace:是否替换原函数1234del frame2['eastern']print(frame2.columns, frame2, sep='\n')print(frame2.drop('one', axis=0))print(frame2.drop(['year', 'debt'], axis=1))
改
列可以通过赋值来修改
通过列表或数组给一列赋值时,所赋的值的长度必须和DataFrame的长度相匹配。
选择、查询
查看数据
- head()、tail(): 查看顶部和底部
- index、column、values: 显示索引,列,和底层numpy数据
- describe(): 描述显示数据快速统计摘要,包括count、mean、std、min、25%、50%、75%、max
- 转置数据:T
- 按轴排序,按值排序123456dates = pd.date_range('20130101', periods=6)df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))print(df, df.head(), df.tail(1),df.index, df.columns, df.values,df.describe(), df.T,df.sort_index(axis=1, ascending=False), df.sort(columns='B'), sep='\n-------\n')
选择数据
选择单列:通过字典记法或属性来检索。建议使用列标签[ ]选取方式,‘.’的写法容易与其他预留关键字产生冲突。返回的Series包含和DataFrame相同的索引,并且继承name 属性。
选择片段:使用[]
使用标签选择
loc(行标签,列标签):
- 行标签和列标签都可以为切片或者单个值
- 两者都为单个值时为选择单个数据,等价于at123print(df.loc[dates[0]], df.loc[:, ['A', 'B']], df.loc['20130102':'20130104', ['A', 'B']], df.loc['20130102', ['A', 'B']], sep='\n------\n')print(df.loc[dates[0], 'A'], df.at[dates[0], 'A'], sep='\n------\n')
按位置选择
iloc(行位置,列位置):
- 行位置和列位置都可以为切片或者单个值
- 两者都为单个值时为选择单个数据,等价于iat1234# 传递整数选择位置print(df.iloc[3], df.iloc[3:5, 0:2], df.iloc[[1, 2, 4], [0, 2]], df.iloc[1:3, :], df.iloc[:, 1:3], sep='\n------\n')# 显式获取一个值(两者等价)print(df.iloc[1, 1], df.iat[1, 1], sep='\n------\n')
布尔索引
跟Series基本一样
索引对象
pandas的索引对象用来保存坐标轴标签和其它元数据(如坐标轴名或名称)。
索引对象是不可变的,从上文Series部分可以看出可以通过整个替换index对象。
类型
pandas中的主要索引对象:
| 分类 | 解释 |
|---|---|
| Index | 最通用的索引对象,使用Python对象的NumPy数组来表示坐标轴标签。 |
| Int64Index | 对整形值的特化索引。 |
| MultiIndex | “分层”索引对象,表示单个轴的多层次的索引。可以被认为是类似的元组的数组。 |
| DatetimeIndex | 存储纳秒时间戳(使用NumPy的datetime64 dtyppe来表示)。 |
| PeriodIndex | 对周期数据(时间间隔的)的特化索引。 |
属性
除了类似于阵列,索引也有类似固定大小集合一样的功能
每个索引都有许多关于集合逻辑的方法和属性:
| 索引方法和属性 | 作用 |
|---|---|
| append | 链接额外的索引对象,产生一个新的索引 |
| diff | 计算索引的差集 |
| intersection | 计算交集 |
| union | 计算并集 |
| isin | 计算出一个布尔数组表示每一个值是否包含在所传递的集合里 |
| delete | 计算删除位置i的元素的索引 |
| drop | 计算删除所传递的值后的索引 |
| insert | 计算在位置i插入元素后的索引 |
| is_monotonic | 返回True,如果每一个元素都比它前面的元素大或相等 |
| is_unique | 返回True,如果索引没有重复的值 |
| unique | 计算索引的唯一值数组 |
重新索引
reindex:根据新的index来进行排序,使得它符合新的索引,如果那个索引的值不存在就引入缺失数据值。
没有的值填充可选配置:
- fill_value: 填充单个值,例如填0
- method: 对时间序列内插或填充
- ffill或pad: 前向(或进位)填充,例如ffill跟前一位相同
- bfill或backfill: 后向(或进位)填充12345678obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'], fill_value=0)obj.index = ['a', 'b', 'c', 'd']print(obj, obj2, sep='\n------\n')obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])obj4 = obj3.reindex(range(6), method='ffill')print(obj4)
reindex与修改index的结果对比:obj vs obj2
DataFrame重新索引
reindex 可以改变(行)索引,列或两者:
- columns:列重新索引
- index: 行重新索引
- 只传入一个序列:相当于index,行重新索引123456frame = pd.DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'],columns=['Ohio', 'Texas', 'California'])frame2 = frame.reindex(['a', 'b', 'c', 'd'])states = ['Texas', 'Utah', 'California']frame3 = frame.reindex(columns=states)print(frame, frame2, frame3, sep='\n------\n')
插值只在行侧(0坐标轴)进行
其他
丢失的数据
pandas主要使用np.nan替换丢失的数据. 默认情况下它并不包含在计算中:
- dropna():删除丢失数据的行,how=’any’表示删除任何
- fillna():填充丢失数据
- isnull():获取值是否nan的布尔标记1234df2 = df[df > 0]print(df2.dropna(how='any'))print(df2.fillna(value=0))print(df2.isnull())
运算
算术运算
基本的加减乘除运算:
二元运算
类似于numpy的运算
- 广播机制
- 缺失数据的计算
- 通过axis指定轴
Apply
在数据上使用函数
字符串方法
具体参见官方文档:Working with Text Data
Merge
pandas提供各种工具以简便合并序列,数据桢,和组合对象, 在连接/合并类型操作中使用多种类型索引和相关数学函数,具体参见官方文档
concat
把pandas对象连接到一起
merge
SQL样式合并:
- on:merge的列
- how:选择左连接、右连接、全连接,默认内连接
- suffixes:重名列后缀1234567891011121314151617left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],'key2': ['K0', 'K1', 'K0', 'K1'],'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3']})right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3', 'K4'],'key2': ['K0', 'K0', 'K0', 'K0', 'K0'],'C': ['C0', 'C1', 'C2', 'C3', 'C4'],'D': ['D0', 'D1', 'D2', 'D3', 'D4']})df3 = pd.merge(left, right, on='key', suffixes=('_left', '_right'))df4 = pd.merge(left, right, on=['key', 'key2'])df5 = pd.merge(left, right, on=['key', 'key2'], how='left')df6 = pd.merge(left, right, on=['key', 'key2'], how='right')df7 = pd.merge(left, right, on=['key', 'key2'], how='outer')print(df3, df4, df5, df6, df7, sep='\n--------\n')
append
添加行到数据增,下例中取第4行,append到df最后一行
Group by
对于“group by”指的是以下一个或多个处理:
- 将数据按某些标准分割为不同的组
- 在每个独立组上应用函数
- 组合结果为一个数据结构12345df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar','foo', 'bar', 'foo', 'foo'],'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],'C': np.random.randn(8),'D': np.random.randn(8)})print(df, df.groupby('A').sum(), df.groupby(['A', 'B']).sum(), sep='\n------\n')
Pivot talbe(数据透视表)
我们可以从此数据非常容易的产生数据透视表:
- values: 聚合列
- index: group列
- columns: 新df的索引列
- aggfunc:聚合函数1234567df = pd.DataFrame({'A': ['one', 'one', 'two', 'three'] * 3,'B': ['A', 'B', 'C'] * 4,'C': ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2,'D': np.random.randn(12),'E': np.random.randn(12)})df_pivot = pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C'])print(df, df_pivot, sep='\n-----pivot-----\n')
参考
Python for Data Analysis
【pandas】[1] Series 入门(创建和增删改查)
【pandas】[2] DataFrame 基础,创建DataFrame和增删改查基本操作(1)
十分钟搞定pandas
官方文档:Indexing and Selecting Data