首页 > 代码库 > pandas 的数据结构(Series, DataFrame)
pandas 的数据结构(Series, DataFrame)
Pandas 讲解
Python Data Analysis Library 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。
pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之一。
Series:一维数组,与Numpy中的一维array类似。 二者与Python基本的数据结构List也很相近,其区别是:List中的元素可以是不同的数据类型, 而Array和Series中则只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率。Time- Series:以时间为索引的Series。DataFrame:二维的表格型数据结构。很多功能与R中的data.frame类似。 可以将DataFrame理解为Series的容器。以下的内容主要以DataFrame为主。Panel :三维的数组,可以理解为DataFrame的容器。
---------------------------------------------------
Series
Series 是一种类似于一维数组的对象, 它由一组数据(各种numpy数据类型)以及一组与之相关的数据标签(索引)组成。
"""In [1]: from pandas import SeriesIn [2]: from pandas import DataFrameIn [3]: obj = Series([4, 7, -5, 3])In [4]: objOut[4]:0 41 72 -53 3dtype: int64"""
Series 索引,指定索引(也就是左边的列)
通过 上面的例子, 我们知道Series的字符表现形式为索引在左边, 值在右边。没有指定索引,
那么索引会自动从0开始的整数型索引
可以通过Series的values和index属性获取其数组表示形式和索引对象。
"""In [5]: obj.valuesOut[5]: array([ 4, 7, -5, 3])In [6]: obj.indexOut[6]: RangeIndex(start=0, stop=4, step=1)"""
那么我们可以自定义索引
In [7]: obj2 = Series([4, 7, -5, 3], index=[‘d‘, ‘b‘, ‘a‘, ‘c‘])In [8]: obj2Out[8]:d 4b 7a -5c 3dtype: int64In [9]: obj2.indexOut[9]: Index([u‘d‘, u‘b‘, u‘a‘, u‘c‘], dtype=‘object‘)
索引赋值
In [11]: obj2[‘d‘] = 9In [12]: obj2Out[12]:d 9b 7a -5c 3dtype: int64
索引取值
In [13]: obj2[["a", "b", "c"]]Out[13]:a -5b 7c 3dtype: int64
索引值映射
In:‘b‘ in obj2Out:TrueIn:‘f‘ in obj2Out:False
通过字典创建Series
"""In [14]: sdata = http://www.mamicode.com/{"Ohio":3500, "Texas":71000, "Oregon":16000, "Utah":51000}In [15]: obj3 = Series(sdata)In [16]: obj3Out[16]:Ohio 3500Oregon 16000Texas 71000Utah 51000dtype: int64"""
索引匹配值和判断缺失
相对应Series也可以匹配对应的索引,如果找不到结果为NaN(非数字),pandas中用于表示缺失的数据
同时isnull和notnull函数用于检测缺失数据。
In [17]: states = [‘California‘, ‘Ohio‘, ‘Oregon‘, ‘Texas‘]In [18]: obj4 = Series(sdata, index=states)In [19]: obj4Out[19]:California NaNOhio 3500.0Oregon 16000.0Texas 71000.0dtype: float64
In [22]: pd.isnull(obj4)Out[22]:California TrueOhio FalseOregon FalseTexas Falsedtype: bool-------------In [23]: pd.notnull(obj4)Out[23]:California FalseOhio TrueOregon TrueTexas Truedtype: bool-----------In [24]: obj4.isnull()Out[24]:California TrueOhio FalseOregon FalseTexas Falsedtype: bool
Series 数据对齐
In [25]: obj3 + obj4Out[25]:California NaNOhio 7000.0Oregon 32000.0Texas 142000.0Utah NaNdtype: float64
name属性
Series 对象本身及其索引都有一个name属性, 该属性跟pandas其他的关键功能关系非常密切
In [26]: obj4.name = ‘population‘In [27]: obj4.index.name = ‘state‘In [29]: obj4Out[29]:stateCalifornia NaNOhio 3500.0Oregon 16000.0Texas 71000.0Name: population, dtype: float64
Series修改索引名称
Series 的索引也可以通过索引的方式就地修改
In [30]: obj.index = [‘Bob‘, ‘Steve‘, ‘Jeff‘, ‘Ryan‘]In [31]: objOut[31]:Bob 4Steve 7Jeff -5Ryan 3dtype: int64
--------------------------------------------------------
DataFrame及常用方法
ix 标签索引 T index和columns变换方向 index reindex
DataFrame 是一个表格行的数据结构, 他含有一组有序的列,每列可以是不同的值类型
(数值,字符串,布尔值等)。
DataFrame既有行索引也有列索引,他可以被看做是由Series组成的字典(共用同一个索引)
跟其他类似的数据结构相比,DataFrame中面向行和面向列的操作基本上是平衡的。
DataFrame 是以二维数据结构保存数据的
构建DataFrame
最常用的一种是直接传入一个有等长列表或Numpy数组组成的字典
In [2]: data = http://www.mamicode.com/{"state": [‘Ohio‘, ‘Ohio‘, ‘Ohio‘, ‘Nevada‘, ‘Nevada‘], ‘year‘:[2000, 2001, 2002, 2001, 2002], ‘pop‘:[1.5, 1.7, 3.6, 2.4, 2.9]}In [3]: from pandas import Series, DataFrameIn [4]: DataFrame(data)Out[4]: pop state year0 1.5 Ohio 20001 1.7 Ohio 20012 3.6 Ohio 20023 2.4 Nevada 20014 2.9 Nevada 2002
另一种嵌套字典生成DataFrame
In [29]: pop = {‘Nevada‘: {2001:2.4, 2003:2.9}, ‘Ohio‘:{2000:1.5, 2001:1.7, 2002:3.6}}In [30]: frame3 = Dataframe(pop)---------------------------------------------------------------------------NameError Traceback (most recent call last)<ipython-input-30-da7c61f3c94a> in <module>()----> 1 frame3 = Dataframe(pop)NameError: name ‘Dataframe‘ is not definedIn [31]: frame3 = DataFrame(pop)In [32]: frame3Out[32]: Nevada Ohio2000 NaN 1.52001 2.4 1.72002 NaN 3.62003 2.9 NaN
DataFrame 的列按照顺序进行排列(列排序)
In [6]: DataFrame(data, columns=[‘year‘, ‘state‘, ‘pop‘])In [7]: dataOut[7]:year state pop0 2000 Ohio 1.51 2001 Ohio 1.72 2002 Ohio 3.63 2001 Nevada 2.44 2002 Nevada 2.9
跟Series一样,如果传入的列在数据中找不到, 就会产生NA值
In [11]: frame2 = DataFrame(data, columns=[‘year‘, ‘state‘, ‘pop‘, ‘debt‘], index=[‘one‘, ‘two‘, ‘three‘, ‘four‘, ‘five‘])In [12]: frame2Out[12]: year state pop debtone 2000 Ohio 1.5 NaNtwo 2001 Ohio 1.7 NaNthree 2002 Ohio 3.6 NaNfour 2001 Nevada 2.4 NaNfive 2002 Nevada 2.9 NaN
axis=0和1分别的表格的纵轴和横轴
通过字典标记(索引)的方式获取一个Series
In [13]: frame2[‘year‘] 也可以写成frame2.yearOut[13]:one 2000two 2001three 2002four 2001five 2002Name: year, dtype: int64
返回的Series拥有同样的索引
行也可以通过位置或名称的方式进行获取,例如用索引字段ix
In [14]: frame2.ix[‘three‘]Out[14]:year 2002state Ohiopop 3.6debt NaNName: three, dtype: object
索引赋值
In [23]: df2.loc[‘d‘] = [i*0 for i in range(len(df2.columns))]In [24]: df2Out[24]: b d e ddUhahdd 0.0 1.0 2.0 0Ohiodd 3.0 4.0 5.0 0Texasdd 6.0 7.0 8.0 0Oregondd 9.0 10.0 11.0 0dd 1.0 2.0 3.0 4d 0.0 0.0 0.0 0
列表推到式还可以写成
map(lambda x:0 if x >0 else 0, a)
列赋值
列可以通过赋值的方式进行修改。例如我们可以给那个空的‘debt’列附上一个附上一个标量或一组值
In [15]: frame2[‘debt‘] = 16.5In [16]: frame2Out[16]: year state pop debtone 2000 Ohio 1.5 16.5two 2001 Ohio 1.7 16.5three 2002 Ohio 3.6 16.5four 2001 Nevada 2.4 16.5five 2002 Nevada 2.9 16.5
In [17]: import numpy as npIn [18]: frame2[‘debt‘] = np.arange(5.)In [19]: frame2Out[19]: year state pop debtone 2000 Ohio 1.5 0.0two 2001 Ohio 1.7 1.0three 2002 Ohio 3.6 2.0four 2001 Nevada 2.4 3.0
将一个列表或数组赋值给某个列时, 如果赋值的是Series, 就会精确匹配DataFrame的索引,
所有的空值将会被填上缺失值。
n [20]: val = Series([1.2, 1.3, -1.2], index=[‘two‘, ‘four‘, ‘five‘])In [21]: frame2[‘debt‘] = valIn [22]: frame2Out[22]: year state pop debtone 2000 Ohio 1.5 NaNtwo 2001 Ohio 1.7 1.2three 2002 Ohio 3.6 NaNfour 2001 Nevada 2.4 1.3five 2002 Nevada 2.9 -1.2
创建列
可以创建新列
In [23]: frame2[‘eastern‘] = frame2.state == ‘Ohio‘In [24]: frame2Out[24]: year state pop debt easternone 2000 Ohio 1.5 NaN Truetwo 2001 Ohio 1.7 1.2 Truethree 2002 Ohio 3.6 NaN Truefour 2001 Nevada 2.4 1.3 Falsefive 2002 Nevada 2.9 -1.2 False
删除列
In [26]: del frame2[‘eastern‘]In [27]: frame2Out[27]: year state pop debtone 2000 Ohio 1.5 NaNtwo 2001 Ohio 1.7 1.2three 2002 Ohio 3.6 NaNfour 2001 Nevada 2.4 1.3five 2002 Nevada 2.9 -1.2
In [28]: frame2.columns
Out[28]: Index([u‘year‘, u‘state‘, u‘pop‘, u‘debt‘], dtype=‘object‘)
结果 行、列倒置,调换位置
In [33]: frame3.TOut[33]: 2000 2001 2002 2003Nevada NaN 2.4 NaN 2.9Ohio 1.5 1.7 3.6 NaN
内层字典的键会被合并、排序以形成最终的索引。如果显示指定了索引, 则按照索引走
In [35]: DataFrame(pop, index=[2001, 2002, 2003, 2004])Out[35]: Nevada Ohio2001 2.4 1.72002 NaN 3.62003 2.9 NaN2004 NaN NaN
也可以根据索引key和切片取值赋值
In [36]: pdata = http://www.mamicode.com/{‘Ohio‘: frame3[‘Ohio‘][:-1], ‘Nevada‘: frame3[‘Nevada‘][:2]}In [39]: DataFrame(pdata)Out[39]: Nevada Ohio2000 NaN 1.52001 2.4 1.72002 NaN 3.6
可以输入给DataFrame构造器的数据
二维ndarray 数据矩阵,还可以传入行标和列标由数组、列表和元组组成的字典 每个序列会变成DataFrame的一列。 所有序列的长度必须相同Numpy的结构化/记录数组 类似于“由数组组成的字典”由Series组成的字典 每个Series会成为一列。如果没有显示指定索引, 则各Series的索引会被合并成结果的行索引由字典组成的字典 各内层字典会成为一列。键会被合并成结果的行索引,跟"由Series组成的字典"的情况一样字典或Series的列表 各项将会成为DataFrame的一行。字典键或Series索引的并集将会成为DataFrame的列标由列标或元组组成的列表 类似于“二维ndarray”另一个DataFrame 该DataFrame的索引将会被沿用,除非显示指定了其他索引Numpy的MaskedArray 类似于"二维ndarray"的情况, 只是掩码值在结果DataFrame会变成NA/缺失值
行标,列标设置别名
In [40]: frame3.index.name = "year"; frame3.columns.name = "state"In [41]: frame3Out[41]:state Nevada Ohioyear2000 NaN 1.52001 2.4 1.72002 NaN 3.62003 2.9 NaN
获取数据
DataFrame以二维ndarray的形式返回数据
In [42]: frame3.valuesOut[42]:array([[ nan, 1.5], [ 2.4, 1.7], [ nan, 3.6], [ 2.9, nan]])
如果DataFrame各列的数据类型不同, 则值数组的数据类型就会选用能兼容所有列的数据类型
----------------------------------------
索引对象
pandas的索引对象负责管理轴标签和其他元数据(比如轴名称等。)构建Series或Data Frame时,所用到的任何数组或其他序列的标签都会被转换成一个Index。
In [1]: from pandas import Series, DataFrameIn [2]: obj = Series(range(3), index=["a", "b", "c"])In [3]: index = obj.indexIn [4]: indexOut[4]: Index([a, b, c], dtype=object)In [5]: objOut[5]:a 0b 1c 2In [6]: index[1:]Out[6]: Index([b, c], dtype=object)
而索引是不可修改的
那么根据上面的例子,报错,证明索引是不可以修改的
In [7]: index[1]Out[7]: ‘b‘In [8]: index[1] = "d"---------------------------------------------------------------------------Exception Traceback (most recent call last)C:\Python27\<ipython-input-8-092906bbf8a9> in <module>()----> 1 index[1] = "d"C:\Python27\lib\site-packages\pandas\core\index.pyc in __setitem__(self, key, value) 307 def __setitem__(self, key, value): 308 """Disable the setting of values."""--> 309 raise Exception(str(self.__class__) + ‘ object is immutable‘) 310 311 def __getitem__(self, key):Exception: <class ‘pandas.core.index.Index‘> object is immutable
而这样做的目的是index对象在多个数据结果之间安全共享
In [11]: index = pd.Index(np.arange(3))In [12]: indexOut[12]: Int64Index([0, 1, 2], dtype=int64)In [13]: obj2 = Series([1.5, -2.5, 0], index=index)In [14]: obj2Out[14]:0 1.51 -2.52 0.0
证明是共享的
In [16]: obj2.index is index
Out[16]: True
pandas中主要的Index对象
Index 最泛化的Index对象, 将轴标签表示为一个由python对象组成的Numpy数组
Int64Index 针对整数的特殊Index
MultiIdex “层次化”索引对象, 表示单个轴上的多层索引。可以看做由元组组成的数组
DatatimeIndex 存储纳秒级时间戳(用NumPy的datatime64类型表示)
PeriodIndex 针对Period数据(时间jiange)的特殊Index
Index的方法和属性
append 连接另一个index对象,产生另一个新的Indexdiff 计算差集,并得到一个indexintersection 计算交集union 计算并集isin 计算一个指示各值是否都包含在参数集合中的布尔型数据delete 删除索引i处的元素,bing得到一个新的Indexdrop 删除传入的值,并得到新的Index
insert 将元素插入到索引i出, 并得到新的index
is_monotonic 当各元素均大于等于前一个元素是,返回True
is_unique 当index没有重复值时,返回True
unique 计算Index中唯一值的数组
In [42]: index3.delete(2)Out[42]: Int64Index([0, 1, 4, 5, 6], dtype=int64)In [28]: index3 = index.append(Index2)In [29]: index3Out[29]: Int64Index([0, 1, 2, 4, 5, 6], dtype=int64)
reindex重新索引 (fill_value 设置默认值)
pandas对象的一个重要方法是reindex, 其作用是创建一个适应新索引的新对象。
而调用Series的reindex将会根据新索引进行重排。如果某个索引值不存在,就引入缺失值。
obj = Series([4.5, 7.l2, -5.3, 3.6], index=[‘d‘, ‘b‘, ‘a‘, ‘c‘])In [25]: obj2 = obj.reindex([i for i in list("abcde")], fill_value=http://www.mamicode.com/0)In [26]: obj2Out[26]:a -5.2b 7.2c 3.6d 4.5e 0.0dtype: float64
但是注意:时间序列这样的有序数据, 重新索引时可能需要做一些插值处理。method选项即可达到目的
例如使用ffill可以实现向前值填充:
In [27]: obj3 = Series(["blue", "purple", "yellow"], index=[0, 2, 4])In [28]: obj3.reindex(range(6), method="ffill")Out[28]:0 blue1 blue2 purple3 purple4 yellow5 yellowdtype: objectIn [29]: obj3Out[29]:0 blue2 purple4 yellowdtype: object
reindex 可以重新 修改(行)索引、列, 或两个都可以修改。传入一个值默认为行索引
In [33]: frame = DataFrame(np.arange(9).reshape((3, 3)), index=[i for i in list(‘abc‘)], columns=["Ohio", "Texas", "California"])In [34]: frameOut[34]: Ohio Texas Californiaa 0 1 2b 3 4 5c 6 7 8In [35]: frame2 = frame.reindex([i for i in list("abcd")])In [36]: frame2Out[36]: Ohio Texas Californiaa 0.0 1.0 2.0b 3.0 4.0 5.0c 6.0 7.0 8.0d NaN NaN NaNIn [37]: states = ["Texas", "Utah", "California"]In [38]: frame.reindex(columns=states)Out[38]: Texas Utah Californiaa 1 NaN 2b 4 NaN 5c 7 NaN 8In [39]: frame.ix[[i for i in list("abcd")], states]Out[39]: Texas Utah Californiaa 1.0 NaN 2.0b 4.0 NaN 5.0c 7.0 NaN 8.0d NaN NaN NaN
-------------------------------------------------------------------
Series 和 DataFrame 丢弃指定轴上的项
丢弃某条轴上的一个或多个项很简单, 只要偶一个索引数组或列表即可。
而drop方法返回的是一个在指定轴上删除了指定值的新对象。
In [46]: obj = Series(np.arange(5.), index=[i for i in list("abcde")])In [47]: objOut[47]:a 0.0b 1.0c 2.0d 3.0e 4.0dtype: float64In [48]: new_obj = obj.drop("c")In [49]: new_objOut[49]:a 0.0b 1.0d 3.0e 4.0dtype: float64In [50]: obj.drop(["b", "c"])Out[50]:a 0.0d 3.0e 4.0dtype: float64
而DataFrame可以删除任意轴上的索引值
In [52]: data = http://www.mamicode.com/DataFrame(np.arange(16).reshape((4,4)), index=["Ohio", "Colorado", "Utah", "New York"], columns=["one", "two", "three", "four"])In [53]: dataOut[53]: one two three fourOhio 0 1 2 3Colorado 4 5 6 7Utah 8 9 10 11New York 12 13 14 15In [54]: data.drop(["Colorado", ""Ohio]) File "<ipython-input-54-8d771dda6c46>", line 1 data.drop(["Colorado", ""Ohio]) ^SyntaxError: invalid syntaxIn [55]: data.drop(["Colorado", "Ohio"])Out[55]: one two three fourUtah 8 9 10 11New York 12 13 14 15-------In [57]: data.drop(["one"], axis=1)Out[57]: two three fourOhio 1 2 3Colorado 5 6 7Utah 9 10 11New York 13 14 15In [58]: data.drop(["one", "four"], axis=1)Out[58]: two threeOhio 1 2Colorado 5 6Utah 9 10New York 13 14
---------------------------------------------
索引选取和过滤
Series
Series 索引(obj[...])的工作方式类似与Numpy数组的索引,只不过Series的索引值不只是整数
In [8]: obj = Series(np.arange(4.), index = [i for i in list("abcd")])In [9]: obj[‘b‘]Out[9]: 1.0In [10]: obj[1]Out[10]: 1.0In [11]: obj[2:4]Out[11]:c 2.0d 3.0dtype: float64In [12]: obj[[‘b‘, ‘c‘, ‘d‘]]Out[12]:b 1.0c 2.0d 3.0dtype: float64In [13]: obj[[1, 3]]Out[13]:b 1.0d 3.0dtype: float64In [14]: obj[obj<2]Out[14]:a 0.0b 1.0dtype: float64
利用索引赋值
In [15]: obj[‘b‘:‘c‘]Out[15]:b 1.0c 2.0dtype: float64In [16]: obj[‘b‘:‘c‘] = 5In [17]: objOut[17]:a 0.0b 5.0c 5.0d 3.0dtype: float64
DataFrame
而DataFrame进行索引就是获取一个或多个列, 默认是columns
data【columns, index】的格式
In [18]: data = http://www.mamicode.com/DataFrame(np.arange(16).reshape((4,4)), index=[‘Ohio‘, ‘Colorado‘, ‘Utah‘, ‘New York‘], columns = [‘one‘, ‘two‘, ‘three‘, ‘four‘])In [19]: dataOut[19]: one two three fourOhio 0 1 2 3Colorado 4 5 6 7Utah 8 9 10 11New York 12 13 14 15In [20]: data[‘two‘]Out[20]:Ohio 1Colorado 5Utah 9New York 13Name: two, dtype: int64In [21]: data[[‘three‘, ‘one‘]]Out[21]: three oneOhio 2 0Colorado 6 4Utah 10 8New York 14 12In [23]: data[:2]Out[23]: one two three fourOhio 0 1 2 3Colorado 4 5 6 7In [24]: data[data[‘three‘] > 5]Out[24]: one two three fourColorado 4 5 6 7Utah 8 9 10 11New York 12 13 14 15
值为bool类型
In [25]: data < 5Out[25]: one two three fourOhio True True True TrueColorado True False False FalseUtah False False False FalseNew York False False False False
重新赋值
In [26]: data[data < 5] = 0In [27]: dataOut[27]: one two three fourOhio 0 0 0 0Colorado 0 5 6 7Utah 8 9 10 11New York 12 13 14 15
DataFrame.ix
如果DataFrame 使用标签索引的话,就是index,需要引入专门的ix,其实就是调换方向
data【index, columns】
In [28]: data.ix[‘Colorado‘, [‘three‘]]Out[28]:three 6Name: Colorado, dtype: int64In [29]: data.ix[[‘Colorado‘, ‘Utah‘], [3, 0, 1]]Out[29]: four one twoColorado 7 0 5Utah 11 8 9
Chrome://flags/#enable-smooth-scrolling
pandas 的数据结构(Series, DataFrame)