# 核心概念
- Pandas是一个高性能的数据操作和分析工具。它在Numpy的基础上,提供了一种高效的DataFrame数据结构,使得在Python中进行数据清洗和分析非常快捷。
- Pandas主要用于处理表格表格型或者异质型数据,而Numpy主要处理同质且是数值类型数据。
- Pandas的核心是三大数据结构:Series、DataFrame和Index。绝大多数操作都是围绕这三种结构进行的。
- Series是一个一维的数组对象,它包含一个值序列和一个对应的索引序列。
- DataFrame是Pandas的核心数据结构,表示的是二维的矩阵数据表,类似关系型数据库的结构,每一列可以是不同的值类型,比如数值、字符串、布尔值等等。
-
# Series
Series是一个一维的数组对象,它包含一个值序列和一个对应的索引序列。
可以为Series对象和其索引设置name属性,有助于标记识别
In [29]: s4.name = 'people' In [30]: s4.index.name= 'city' In [31]: s4 Out[31]: city nanjing NaN shanghai 71000.0 guangzhou 16000.0 beijing 35000.0 Name: people, dtype: float64 In [32]: s4.index Out[32]: Index(['nanjing', 'shanghai', 'guangzhou', 'beijing'], dtype='object', name='city')可以分别通过values和index属性分别获取Series对象的值和索引。
In [6]: s.values Out[6]: array([ 7, -3, 4, -2], dtype=int64) In [7]: s.index Out[7]: RangeIndex(start=0, stop=4, step=1)
Numpy的一维数组通过隐式定义的整数索引获取元素值,而Series用一种显式定义的索引与元素关联。
显式索引让Series对象拥有更强的能力,索引也不再仅仅是整数,还可以是别的类型,比如字符串,索引也不需要连续,也可以重复,自由度非常高。
In [1]: import pandas as pd In [2]: s = pd.Series([7,-3,4,-2]) In [3]: s Out[3]: 0 7 1 -3 2 4 3 -2 dtype: int64可以在创建时指定索引,还可以通过索引去筛选结果(使用dict创造字典时,不存在的值为NaN)
In [8]: s2 = pd.Series([7,-3,4,-2], index=['d','b','a','c']) In [9]: s2 Out[9]: d 7 b -3 a 4 c -2 dtype: int64 In [10]: s2.index Out[10]: Index(['d', 'b', 'a', 'c'], dtype='object') In [5]: pd.Series({2:'a',1:'b',3:'c'}, index=[3,2]) # 通过index筛选结果 Out[5]: 3 c 2 a dtype: object索引可以被修改
In [33]: s Out[33]: 0 7 1 -3 2 4 3 -2 dtype: int64 In [34]: s.index = ['a','b','c','d'] In [35]: s Out[35]: a 7 b -3 c 4 d -2 dtype: int64可以通过索引获取值
In [11]: s2['a'] Out[11]: 4 In [12]: s2[['c','a','d']] Out[12]: c -2 a 4 d 7 dtype: int64索引可以使用in操作,因为Series比较类似Python的有序字典
In [17]: 'b' in s2 Out[17]: True In [18]: 'e'in s2 Out[18]: False实际上默认还有一个从0开始的索引供我们使用
注意:如果你的Series是显式的整数索引,那么
s[1]这样的取值操作会使用显式索引,而s[1:3]这样的切片操作却会使用隐式索引。(这是一个历史遗留问题)
可以对Series执行一些类似Numpy的通用函数操作
In [13]: s2[s2>0] Out[13]: d 7 a 4 dtype: int64 In [14]: s2*2 Out[14]: d 14 b -6 a 8 c -4 dtype: int64可以使用isnull和notnull来检查缺失的数据
In [25]: pd.isnull(s4) Out[25]: nanjing True shanghai False guangzhou False beijing False dtype: bool In [26]: pd.notnull(s4) Out[26]: nanjing False shanghai True guangzhou True beijing True dtype: bool In [27]: s4.isnull() Out[27]: nanjing True shanghai False guangzhou False beijing False dtype: bool
# DataFrame
DataFrame是Pandas的核心数据结构,表示的是二维的矩阵数据表,类似关系型数据库的结构
DataFrame每一列可以是不同的值类型,比如数值、字符串、布尔值等等。
DataFrame中,一切优先按列操作。
DataFrame既有行索引,也有列索引,它可以被看做为一个共享相同索引的Series的字典。
可以通过columns,index和values分别查看DataFrame对象的columns和index属性以及DataFrame的值。
In [39]: f Out[39]: state year pop 0 beijing 2000 1.5 1 beijing 2001 1.7 2 beijing 2002 3.6 3 shanghai 2001 2.4 4 shanghai 2002 2.9 5 shanghai 2003 3.2 In [61]: f.columns Out[61]: Index(['state', 'year', 'pop'], dtype='object') In [62]: f.index Out[62]: RangeIndex(start=0, stop=6, step=1)创建时可以指定columns和index
In [45]: f2 = pd.DataFrame(data, columns=['year','state','pop'],index=['a','b','c','d','e','f']) In [47]: f2 Out[47]: year state pop a 2000 beijing 1.5 b 2001 beijing 1.7 c 2002 beijing 3.6 d 2001 shanghai 2.4 e 2002 shanghai 2.9 f 2003 shanghai 3.2DataFrame可以为列和索引设置名字
In [70]: f2.index.name = 'order';f2.columns.name='key'
可以使用columns来检索某一列
In [49]: f2['year'] # f2.year也可以,但bug多. 例如属性名不是纯字符串时或者与其他方法同名等... Out[49]: a 2000 b 2001 c 2002 d 2001 e 2002 f 2003 Name: year, dtype: int64可以直接追加列
In [54]: f2['debt'] = 12 In [55]: f2 Out[55]: year state pop debt a 2000 beijing 1.5 12 b 2001 beijing 1.7 12 c 2002 beijing 3.6 12 d 2001 shanghai 2.4 12 e 2002 shanghai 2.9 12 f 2003 shanghai 3.2 12 In [56]: f2['debt'] = np.arange(1,7) In [57]: f2 Out[57]: year state pop debt a 2000 beijing 1.5 1 b 2001 beijing 1.7 2 c 2002 beijing 3.6 3 d 2001 shanghai 2.4 4 e 2002 shanghai 2.9 5 f 2003 shanghai 3.2 6 In [58]: val = pd.Series([1,2,3],index = ['c','d','f']) In [59]: f2['debt'] = val In [60]: f2 # 缺失值以NaN填补 Out[60]: year state pop debt a 2000 beijing 1.5 NaN b 2001 beijing 1.7 NaN c 2002 beijing 3.6 1.0 d 2001 shanghai 2.4 2.0 e 2002 shanghai 2.9 NaN f 2003 shanghai 3.2 3.0使用del方法删除指定列
del f2['new']
可以通过loc方法选取某一行,以指定的显式索引进行索引。
In [53]: f2.loc['a'] Out[53]: year 2000 state beijing pop 1.5 Name: a, dtype: object使用append方法追加行
>>> df1 = df.loc['a'] >>> df1 state beijing year 2000 pop 1.5 Name: a, dtype: object >>> df.append(df1) state year pop a beijing 2000 1.5 b beijing 2001 1.7 c beijing 2002 3.6 d shanghai 2001 2.4 e shanghai 2002 2.9 f shanghai 2003 3.2 a beijing 2000 1.5也可以使用iloc方法选取某一行,iloc以隐含的整数索引进行索引。
可以使用类似Numpy的T属性,将DataFrame进行转置
可以使用info方法查看DataFrame的整体信息情况
In [73]: f.info() Out[73]: <class 'pandas.core.frame.DataFrame'> RangeIndex: 6 entries, 0 to 5 Data columns (total 3 columns): state 6 non-null object year 6 non-null int64 pop 6 non-null float64 dtypes: float64(1), int64(1), object(1) memory usage: 224.0+ bytes
# Index
Pandas 中的索引对象Index用于存储轴标签和其它元数据,不可变。
索引可以使用in操作,因为其本质上是一个容器对象。
In [84]: f2 Out[84]: key year state pop debt order a 2000 beijing 1.5 NaN b 2001 beijing 1.7 NaN c 2002 beijing 3.6 1.0 d 2001 shanghai 2.4 2.0 e 2002 shanghai 2.9 NaN f 2003 shanghai 3.2 3.0 In [86]: 'c' in f2.index Out[86]: True In [88]: 'pop' in f2.columns Out[88]: True索引可以包含重复的标签,同时可以查看其is_unique属性来判断是否存在重复的所有
In [89]: dup_lables = pd.Index(['foo','foo','bar','bar']) In [90]: dup_lables Out[90]: Index(['foo', 'foo', 'bar', 'bar'], dtype='object')In [91]: f2.index = ['a']*6 In [92]: f2 Out[92]: key year state pop debt a 2000 beijing 1.5 NaN a 2001 beijing 1.7 NaN a 2002 beijing 3.6 1.0 a 2001 shanghai 2.4 2.0 a 2002 shanghai 2.9 NaN a 2003 shanghai 3.2 3.0 In [93]: f2.loc['a'] Out[93]: key year state pop debt a 2000 beijing 1.5 NaN a 2001 beijing 1.7 NaN a 2002 beijing 3.6 1.0 a 2001 shanghai 2.4 2.0 a 2002 shanghai 2.9 NaN a 2003 shanghai 3.2 3.0 In [94]: f2.columns = ['year']*4 In [95]: f2 Out[95]: year year year year a 2000 beijing 1.5 NaN a 2001 beijing 1.7 NaN a 2002 beijing 3.6 1.0 a 2001 shanghai 2.4 2.0 a 2002 shanghai 2.9 NaN a 2003 shanghai 3.2 3.0当使用reindex时不是就地修改,而是参照原有数据,调整顺序,并将不存在的索引引入缺失值。
In [96]: obj=pd.Series([4.5,7.2,-5.3,3.6],index = ['d','b','a','c']) In [97]: obj Out[97]: d 4.5 b 7.2 a -5.3 c 3.6 dtype: float64 In [99]: obj2 = obj.reindex(list('abcde')) In [100]: obj2 Out[100]: a -5.3 b 7.2 c 3.6 d 4.5 e NaN dtype: float64可以为缺失值指定填充方式method参数,比如ffill表示向前填充,bfill表示向后填充
In [101]: obj3 = pd.Series(['blue','purple','yellow'],index = [0,2,4]) In [102]: obj3 Out[102]: 0 blue 2 purple 4 yellow dtype: object In [103]: obj3.reindex(range(6),method='ffill') Out[103]: 0 blue 1 blue 2 purple 3 purple 4 yellow 5 yellow dtype: object当reindex只提供一个列表参数时默认是修改行索引,可以使用关键词参数columns指定修改列索引。
使用map方法可以修改原油的index
本质上map是对每一个元素执行一样的操作,而Index实质上也是一个容器
In [83]: df = pd.DataFrame(np.arange(12).reshape((3, 4)), ...: index=['Ohio', 'Colorado', 'New York'], ...: columns=['one', 'two', 'three', 'four']) ...: In [84]: transform = lambda x: x[:4].upper() # 截取前4个字符并大写 In [85]: df.index.map(transform) # map的结果 Out[85]: Index(['OHIO', 'COLO', 'NEW '], dtype='object')或者传入一个字典,将指定的索引命名成新值,不会修改原有值(除非设置inplace=True)
In [90]: df.rename(index={'OHIO': 'INDIANA'}, ...: columns={'three': 'peekaboo'}) ...: Out[90]: one two peekaboo four INDIANA 0 1 2 3 COLO 4 5 6 7 NEW 8 9 10 11
使用rename方法修改索引但是不会修改原有数据
In [88]: df.rename(index=str.title, columns=str.upper) Out[88]: ONE TWO THREE FOUR Ohio 0 1 2 3 Colo 4 5 6 7 New 8 9 10 11 In [89]: df # 原值未变 Out[89]: one two three four OHIO 0 1 2 3 COLO 4 5 6 7 NEW 8 9 10 11