首页 > 代码库 > 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([ud, ub, ua, uc], 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 = populationIn [27]: obj4.index.name = stateIn [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 == OhioIn [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]: bIn [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
View Code

值为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
View Code

重新赋值

技术分享
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
View Code

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)