pandas入门(1)数据结构介绍、基本功能

pandas是基于NumPy构建的,含有使数据分析工作变得更快更简单的高级数据结构和操作工具。

from pandas import Series,DataFrame
import pandas as pd

pandas的数据结构介绍

主要数据结构:SeriesDataFrame

Series:

是一种类似于一维数组的对象,它由一组数据(各种numpy数据类型)以及一组与之相关的数据标签(即索引)组成。
仅由一组数据即可产生最简单的Series:

In [32]: obj = Series([4, 7, -5, 3])

In [33]: obj
Out[33]: 
0    4
1    7
2   -5
3    3
dtype: int64

Series的字符串表现形式:索引在左边,值在右边;由于没有指定索引,会自动创建一个0N1的整数型索引;

可以通过Seriesvaluesindex属性获取其数组表示形式和索引对象:

In [34]: obj.values
Out[34]: array([ 4,  7, -5,  3])

In [35]: obj.index
Out[35]: RangeIndex(start=0, stop=4, step=1)

通常我们希望创建的Series带有一个可以对各个数据点进行标记的索引:

In [36]: obj2 = Series([4, 7, -5, 3], index=['d','b','a','c'])

In [37]: obj2
Out[37]: 
d    4
b    7
a   -5
c    3
dtype: int64

In [38]: obj2.index
Out[38]: Index(['d', 'b', 'a', 'c'], dtype='object'

与普通numpy数组相比,可以通过索引的方式选取Series中的单个或一组值:

In [39]: obj2['a']
Out[39]: -5

In [41]: obj2[['c','a','d']]
Out[41]: 
c    3
a   -5
d    4
dtype: int64

numpy数组运算都会保留索引和值之间的链接:

In [42]: obj2[obj2 > 0]
Out[42]: 
d    4
b    7
c    3
dtype: int64

In [44]: np.exp(obj2)
Out[44]: 
d      54.598150
b    1096.633158
a       0.006738
c      20.085537
dtype: float64

还可以将Series看成是一个定长的有序字典,因为它是索引值到数据值的一个映射:

In [45]: 'b' in obj2       In [46]: 'a' in obj2       In [47]: 'e' in obj2
Out[45]: True              Out[46]: True              Out[47]: False 

如果数据被存放在一个Python字典中,可直接通过字典创建Series

In [48]: sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah':5000}

In [49]: onj3 = Series(sdata)

In [50]: onj3
Out[50]: 
Ohio      35000
Oregon    16000
Texas     71000
Utah       5000
dtype: int64

而且,传入的字典的键就是Series结果中的索引;

In [51]: states = ['California', 'Ohio', 'Oregon','Texas']

In [52]: obj4 = Series(sdata, index=states)

In [53]: obj4
Out[53]: 
California        NaN
Ohio          35000.0
Oregon        16000.0
Texas         71000.0
dtype: float64

sdata中跟states索引相匹配的值会被找出并放到相应位置,
NaN(非数字,not a number)在pandas中用于表示缺失(missing)或NA值,
pandasisnullnotnull函数可用于检测缺失数据:

In [54]: pd.isnull(obj4)
Out[54]: 
California     True
Ohio          False
Oregon        False
Texas         False
dtype: bool

In [55]: pd.notnull(obj4)
Out[55]: 
California    False
Ohio           True
Oregon         True
Texas          True
dtype: bool

pandas中还有类似的实例方法:

In [56]: obj4.isnull()
Out[56]: 
California     True
Ohio          False
Oregon        False
Texas         False
dtype: bool

对于许多应用而言,Series最重要的一个功能是:他在算数运算中会自动对齐不同索引的数据。

In [57]: onj3         In [58]: obj4
Out[57]:              Out[58]:
Ohio      35000       California    NaN
Oregon    16000       Ohio      35000.0
Texas     71000       Oregon    16000.0
Utah       5000       Texas     71000.0
dtype: int64          dtype: float64

In [59]: onj3 + obj4
Out[59]: 
California         NaN
Ohio           70000.0
Oregon         32000.0
Texas         142000.0
Utah               NaN
dtype: float64

Series对象本身及其索引都有一个name属性,该属性跟pandas其他的关键功能关系非常密切:

In [60]: obj4.name = 'population'

In [61]: obj4.index.name = 'state'

In [62]: obj4
Out[62]: 
state
California        NaN
Ohio          35000.0
Oregon        16000.0
Texas         71000.0
Name: population, dtype: float64
Series的索引可以通过赋值的方式就地修改:
In [63]: obj.index = ['Bob', 'Steve', 'Jeff’, 'Ryan']

In [64]: obj
Out[64]: 
Bob      4
Steve    7
Jeff    -5
Ryan     3
dtype: int64

DataFrame:

DataFrame是一个表格型的数据结构,含有一组有序的列,每列可以是不同的值类型。既有行索引,也有列索引,可以被看做由Series组成的字典。

构建DataFrame:最常用的是直接传入一个由等长列表或NumPy数组组成的字典:

In [3]: data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'year': [2000, 2001, 2002, 2001, 2002], 'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
In [4]: frame = DataFrame(data)

结果DataFrame会自动加上索引,且全部列会被有序排列:

In [5]: frame
Out[5]: 
   pop   state  year
0  1.5    Ohio  2000
1  1.7    Ohio  2001
2  3.6    Ohio  2002
3  2.4  Nevada  2001
4  2.9  Nevada  2002

如果指定了列序列,则按照指定顺序排列:

In [6]: DataFrame(data, columns=['year', 'state', 'pop'])
Out[6]: 
   year   state  pop
0  2000    Ohio  1.5
1  2001    Ohio  1.7
2  2002    Ohio  3.6
3  2001  Nevada  2.4
4  2002  Nevada  2.9

Series一样,如果传入的列在数据中找不到,就会产生NA值:

In [9]: frame2 = DataFrame(data, columns=['year', 'state', 'pop', 'debt'], index=['one', 'two', 'three', 'four', 'five'])

In [10]: frame2
Out[10]: 
       year   state  pop debt
one    2000    Ohio  1.5  NaN
two    2001    Ohio  1.7  NaN
three  2002    Ohio  3.6  NaN
four   2001  Nevada  2.4  NaN
five   2002  Nevada  2.9  NaN

通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series(返回的Series拥有原DataFrame相同的索引,name属性相应的被设置好):

In [11]: frame2['state']
Out[11]: 
one        Ohio
two        Ohio
three      Ohio
four     Nevada
five     Nevada
Name: state, dtype: object

列可以通过赋值的方式进行修改:

In [12]: frame2['debt'] = 18.5

In [13]: frame2
Out[13]: 
       year   state  pop  debt
one    2000    Ohio  1.5  18.5
two    2001    Ohio  1.7  18.5
three  2002    Ohio  3.6  18.5
four   2001  Nevada  2.4  18.5
five   2002  Nevada  2.9  18.5

将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度匹配;如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值:

In [14]: val = Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
In [15]: frame2['debt'] = val

In [16]: frame2
Out[16]: 
       year   state  pop  debt
one    2000    Ohio  1.5   NaN
two    2001    Ohio  1.7  -1.2
three  2002    Ohio  3.6   NaN
four   2001  Nevada  2.4  -1.5
five   2002  Nevada  2.9  -1.7

为不存在的列赋值会创建一个新的列;关键字del用于删除列:

In [17]: frame2['eastern'] = frame2.state == 'Ohio'
In [18]: frame2
Out[18]: 
       year   state  pop  debt  eastern
one    2000    Ohio  1.5   NaN     True
two    2001    Ohio  1.7  -1.2     True
three  2002    Ohio  3.6   NaN     True
four   2001  Nevada  2.4  -1.5    False
five   2002  Nevada  2.9  -1.7    False

In [19]: del frame2['eastern']
In [20]: frame2
Out[20]: 
       year   state  pop  debt
one    2000    Ohio  1.5   NaN
two    2001    Ohio  1.7  -1.2
three  2002    Ohio  3.6   NaN
four   2001  Nevada  2.4  -1.5
five   2002  Nevada  2.9  -1.7

!!!!:通过索引方式返回的列只是相应数据的视图而已,不是副本;因此,对返回的Series做修改会反映到源数据上;

通过Seriescopy方法可以显式地复制列。

如果将嵌套字典传给DataFrame,会被解释为:外层字典的键作为列,内层键作为行索引:

内层字典的键会被合并、排序以形成最终的索引:

In [21]: pop = {'Nevada': {2001: 2.4, 2002: 2.9}, 'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}

In [22]: frame3 = DataFrame(pop)

In [23]: frame3
Out[23]: 
      Nevada  Ohio
2000     NaN   1.5
2001     2.4   1.7
2002     2.9   3.6

DataFrame构造函数能接受的数据类型:见#2109

如果设置了DataFrameindexcolumnsname属性:

In [25]: frame3.index.name = 'year'; frame3.columns.name = 'state'

In [26]: frame3
Out[26]: 
state  Nevada  Ohio
year               
2000      NaN   1.5
2001      2.4   1.7
2002      2.9   3.6

Series一样,values属性也会以二维ndarray的形式返回DataFrame中的数据:

In [27]: frame3.values
Out[27]: 
array([[ nan,  1.5],
       [ 2.4,  1.7],
       [ 2.9,  3.6]])

如果各列的数据类型不同,则值数组的数据类型就会选用能兼容所有列的数据类型:

In [28]: frame2.values
Out[28]: 
array([[2000, 'Ohio', 1.5, nan],
       [2001, 'Ohio', 1.7, -1.2],
       [2002, 'Ohio', 3.6, nan],
       [2001, 'Nevada', 2.4, -1.5],
       [2002, 'Nevada', 2.9, -1.7]], dtype=object)

索引对象:

pandas的索引对象负责管理:轴标签,其他元数据(比如轴名称等);

构建SeriesDataFrame时,所用到的任何数组或其他序列的标签都会被转换成一个Index

In [29]: obj = Series(range(3), index=['a', 'b', 'c'])
In [30]: index = obj.index

In [31]: index
Out[31]: Index(['a', 'b', 'c'], dtype='object')

index对象是不可修改的(immutable):
不可修改性很重要,这样能够使Index对象在多个数据结构之间安全共享:

In [35]: index = pd.Index(np.arange(3))
In [36]: obj2 = Series([1.5, -2.5, 0], index=index)

In [37]: obj2.index is index
Out[37]: True

Index的功能类似一个固定大小的集合:

In [39]: frame3
Out[39]: 
state  Nevada  Ohio
year               
2000      NaN   1.5
2001      2.4   1.7
2002      2.9   3.6

In [40]: 'Ohio' in frame3.columns
Out[40]: True

In [41]: 2003 in frame3.index
Out[41]: False

每个索引都有一些方法和属性,他们可用于设置逻辑并回答有关该索引所包含的数据的常见问题:
见#2139

基本功能:

(介绍操作SeriesDataFrame中的数据的基本手段,常用的重要功能)

重新索引:

reindex,创建一个适应新索引的新对象,即根据新索引进行重排;当前不存在值的索引引入缺失值:

In [42]: obj = Series([1, 2.4, 4.6, 7], index=['c', 'd', 'a', 'b'])
In [43]: obj
Out[43]: 
c    1.0
d    2.4
a    4.6
b    7.0
dtype: float64

In [44]: obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
In [45]: obj2
Out[45]: 
a    4.6
b    7.0
c    1.0
d    2.4
e    NaN
dtype: float64

对于时间序列这样的有序数据,重新索引时可能需要做一些插值处理。

method选项可以达到目的,例如ffill可以实现前向值填充:

  • ffill/pad:前向填充值;
  • bfill/backfill:后项值填充;
In [46]: obj3 = Series(['blue', 'yellow', 'purple'], index=[0, 2, 4])

In [47]: obj3.reindex(range(6), method='ffill')
Out[47]: 
0      blue
1      blue
2    yellow
3    yellow
4    purple
5    purple
dtype: object

对于DataFramereindex可以修改行索引、列或两个都修改。

如果只传入一个序列,则会重新索引行:

In [49]: frame = DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'], columns=['Ohio', 'Texas', 'California'])
In [50]: frame
Out[50]: 
   Ohio  Texas  California
a     0      1           2
c     3      4           5
d     6      7           8

In [51]: frame2 = frame.reindex(['a', 'b', 'c', 'd'])
In [52]: frame2
Out[52]: 
   Ohio  Texas  California
a   0.0    1.0         2.0
b   NaN    NaN         NaN
c   3.0    4.0         5.0
d   6.0    7.0         8.0

使用columns关键字即可重新索引列:

In [53]: states = ['Texas', 'Utah', 'California']
In [54]: frame.reindex(columns=states)
Out[54]: 
   Texas  Utah  California
a      1   NaN           2
c      4   NaN           5
d      7   NaN           8

同时对行和列重新索引,插值只能按行应用(轴0),列不填充:

frame.reindex(index=['a', 'b', 'c', 'd'], columns=['Texas', 'Utah', 'Ca ...: lifornia'])

利用ix的标签索引功能,重新索引任务可以变得更简洁:

In [58]: frame.ix[['a','b','c','d'], states]
Out[58]: 
   Texas  Utah  California
a    1.0   NaN         2.0
b    NaN   NaN         NaN
c    4.0   NaN         5.0
d    7.0   NaN         8.0

reindex函数的参数见#2176

丢弃指定轴上的项:

传入一个索引数组或列表即可,由于需要执行一些数据整理和集合逻辑,所以drop方法返回的是一个在制定轴上删除了指定值的新对象:

In [60]: obj = Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])

In [61]: new_obj = obj.drop('c')
In [62]: new_obj
Out[62]: 
a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64

In [63]: obj.drop(['d', 'c'])
Out[63]: 
a    0.0
b    1.0
e    4.0
dtype: float64

对于DataFrame,可以删除任意轴上的索引值:

In [64]: data = DataFrame(np.arange(16).reshape((4,4)), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['one', 'two
    ...: ', 'three', 'four'])

In [65]: data.drop(['Colorado', 'Ohio'])
Out[65]: 
          one  two  three  four
Utah        8    9     10    11
New York   12   13     14    15

In [66]: data.drop('two', axis=1)
Out[66]: 
          one  three  four
Ohio        0      2     3
Colorado    4      6     7
Utah        8     10    11
New York   12     14    15

说明:
实际上axis = 1,指的是沿着行求所有列的平均值,代表了横轴,那axis = 0,就是沿着列求所有行的平均值,代表了纵轴。

0,1轴示意图

那这样的话,drop就是沿着'two'的方向删除对应的轴标签为axis = 1的值。

索引、选取和过滤:

Series索引(obj[…])的工作方式类似于NumPy数组的索引,只不过Series的索引值不只是整数:

In [67]: obj = Series(np.arange(4.), index=['a', 'b', 'c', 'd'])

In [68]: obj[2:4]
Out[68]: 
c    2.0
d    3.0
dtype: float64

In [69]: obj[['b', 'a', 'd']]
Out[69]: 
b    1.0
a    0.0
d    3.0
dtype: float64

利用标签的切片运算与普通的Python切片运算不同,其末端是包含的(inclusive),即封闭区间:

In [70]: obj['b':'d']
Out[70]: 
b    1.0
c    2.0
d    3.0
dtype: float64

设置的方式也很简单:

In [71]: obj['b':'c'] = 5
In [72]: obj
Out[72]: 
a    0.0
b    5.0
c    5.0
d    3.0
dtype: float64

DataFrame进行索引其实就是获取一个或多个列:

In [73]: data
Out[73]: 
          one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15

In [74]: data[['one', 'three']]
Out[74]: 
          one  three
Ohio        0      2
Colorado    4      6
Utah        8     10
New York   12     14

这种索引方式有几个特殊的情况:

  1. 通过切片或布尔型数组选取行:
In [76]: data[2:]
Out[76]: 
          one  two  three  four
Utah        8    9     10    11
New York   12   13     14    15

n [77]: data[data['three'] > 5]
Out[77]: 
          one  two  three  four
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15
  1. 通过布尔型DataFrame进行索引:
In [78]: bool = data < 5
In [79]: bool
Out[79]: 
            one    two  three   four
Ohio       True   True   True   True
Colorado   True  False  False  False
Utah      False  False  False  False
New York  False  False  False  False

In [80]: data[bool] = 0
In [81]: data
Out[81]: 
          one  two  three  four
Ohio        0    0      0     0
Colorado    0    5      6     7
Utah        8    9     10    11
New York   12   13     14    15

索引字段ix可以通过NumPy式的标记法以及轴标签从DataFrame中选取行和列的子集:

loc获取行子集,iloc通过行号获取,ix综合两者:

In [84]: data.ix['Colorado', ['two', 'four']]
Out[84]: 
two     5
four    7
Name: Colorado, dtype: int64

算术运算和数据对齐:

pandas可以对不同索引的对象进行算术运算,如果存在不同的索引对,结果取并集:

自动对齐操作在不重叠的所引处引入NA值。

In [87]: s1 = Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])
In [88]: s2 = Series([-2.1, 3.6, -1.5, 4, 3.1], index=['a', 'c', 'e', 'f', 'g’])

In [89]: s1
Out[89]: 
a    7.3
c   -2.5
d    3.4
e    1.5
dtype: float64

In [90]: s2
Out[90]: 
a   -2.1
c    3.6
e   -1.5
f    4.0
g    3.1
dtype: float64

In [91]: s1 + s2
Out[91]: 
a    5.2
c    1.1
d    NaN
e    0.0
f    NaN
g    NaN
dtype: float64

对于DataFrame,对齐操作会同时发生在行和列上:

相加后会返回一个新的DataFrame,其索引和列为原来的那两个DataFrame的并集:

In [94]: df1 = DataFrame(np.arange(9).reshape((3,3)), columns=list('bcd'), index
    ...: =['Ohio', 'Texas', 'Colorado'])
In [95]: df2 = DataFrame(np.arange(12).reshape((4,3)), columns=list('bde'), inde
    ...: x=['Utah', 'Ohio', 'Texas', 'Oregon'])

In [96]: df1
Out[96]: 
          b  c  d
Ohio      0  1  2
Texas     3  4  5
Colorado  6  7  8

In [97]: df2
Out[97]: 
        b   d   e
Utah    0   1   2
Ohio    3   4   5
Texas   6   7   8
Oregon  9  10  11

In [98]: df1 + df2
Out[98]: 
            b   c     d   e
Colorado  NaN NaN   NaN NaN
Ohio      3.0 NaN   6.0 NaN
Oregon    NaN NaN   NaN NaN
Texas     9.0 NaN  12.0 NaN
Utah      NaN NaN   NaN NaN

在算数方法中填充值:

在对不同索引的对象进行算术运算时,当一个对象中某个轴标签在另一个对象中找不到时填充一个特殊值:

使用df1add方法(sub\div\mul),传入df2以及一个fill_value参数

In [99]: df1 = DataFrame(np.arange(12.).reshape((3,4)), columns=list('abcd'))
In [100]: df2 = DataFrame(np.arange(20.).reshape((4,5)), columns=list('abcde'))

In [101]: df1
Out[101]: 
     a    b     c     d
0  0.0  1.0   2.0   3.0
1  4.0  5.0   6.0   7.0
2  8.0  9.0  10.0  11.0

In [102]: df2
Out[102]: 
      a     b     c     d     e
0   0.0   1.0   2.0   3.0   4.0
1   5.0   6.0   7.0   8.0   9.0
2  10.0  11.0  12.0  13.0  14.0
3  15.0  16.0  17.0  18.0  19.0

In [103]: df1.add(df2, fill_value=0)
Out[103]: 
      a     b     c     d     e
0   0.0   2.0   4.0   6.0   4.0
1   9.0  11.0  13.0  15.0   9.0
2  18.0  20.0  22.0  24.0  14.0
3  15.0  16.0  17.0  18.0  19.0

DataFrame和Series之间的运算:

广播(broadcasting):
In [104]: arr = np.arange(12).reshape((3,4))

In [105]: arr
Out[105]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

In [106]: arr[0]
Out[106]: array([0, 1, 2, 3])

In [107]: arr - arr[0]
Out[107]: 
array([[0, 0, 0, 0],
       [4, 4, 4, 4],
       [8, 8, 8, 8]])

默认情况下,DataFrameSeries之间的算术运算会将Series的索引匹配到DataFrame的列,然后沿着行一直向下广播:

In [108]: frame = DataFrame(np.arange(12).reshape((4,3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])
In [111]: series = frame.iloc[0]

In [112]: frame
Out[112]: 
        b   d   e
Utah    0   1   2
Ohio    3   4   5
Texas   6   7   8
Oregon  9  10  11

In [113]: series
Out[113]: 
b    0
d    1
e    2
Name: Utah, dtype: int64

In [114]: frame - series
Out[114]: 
        b  d  e
Utah    0  0  0
Ohio    3  3  3
Texas   6  6  6
Oregon  9  9  9

如果某个索引值在DataFrame的列或Series的索引中找不到,则参与运算的两个对象就会被重新索引以形成并集:

In [115]: series2 = Series(range(3), index=['b', 'e', 'f'])

In [116]: frame + series2
Out[116]: 
          b   d     e   f
Utah    0.0 NaN   3.0 NaN
Ohio    3.0 NaN   6.0 NaN
Texas   6.0 NaN   9.0 NaN
Oregon  9.0 NaN  12.0 NaN

如果希望匹配行且在列上广播,则必须使用算术运算方法:
传入的轴号就是希望匹配的轴

In [117]: series3 = frame['d']

In [118]: frame
Out[118]: 
        b   d   e
Utah    0   1   2
Ohio    3   4   5
Texas   6   7   8
Oregon  9  10  11

In [119]: series3
Out[119]: 
Utah       1
Ohio       4
Texas      7
Oregon    10
Name: d, dtype: int64

In [120]: frame.sub(series3, axis=0)
Out[120]: 
        b  d  e
Utah   -1  0  1
Ohio   -1  0  1
Texas  -1  0  1
Oregon -1  0  1

函数应用和映射:

NumPyufuncs(元素级数组方法)也可用于操作pandas对象:

In [122]: frame = DataFrame(np.random.randn(4, 3), columns=list('bde'), index=['Utah'
     ...: , 'Ohio', 'Texas', 'Oregon'])

In [123]: frame
Out[123]: 
               b         d         e
Utah    0.811566  1.357208 -0.603041
Ohio    0.149760  1.201341 -0.147990
Texas   1.040389  0.413789  1.399404
Oregon -0.553470 -0.666800 -0.463801

In [124]: np.abs(frame)
Out[124]: 
               b         d         e
Utah    0.811566  1.357208  0.603041
Ohio    0.149760  1.201341  0.147990
Texas   1.040389  0.413789  1.399404
Oregon  0.553470  0.666800  0.463801

另一个常见的操作是,将函数应用到由各列或行所形成的一维数组上;

DataFrameapply方法即可实现此功能:

In [125]: f = lambda x:x.max() - x.min()

In [126]: frame.apply(f)
Out[126]: 
b    1.593859
d    2.024008
e    2.002445
dtype: float64

In [128]: frame.apply(f, axis=1)
Out[128]: 
Utah      1.960249
Ohio      1.349331
Texas     0.985615
Oregon    0.202998
dtype: float64

除了标量值外,传递给apply的函数还可以返回由多个值组成的Series

In [129]: def f(x):
     ...:     return Series([x.min(), x.max()], index=['min', 'max'])
     ...: 

In [130]: frame.apply(f)
Out[130]: 
            b         d         e
min -0.553470 -0.666800 -0.603041
max  1.040389  1.357208  1.399404

此外,元素级的python函数也是可以用的。假如你想得到frame中各个浮点值的格式化字符串,使用applymap即可:

In [131]: format = lambda x: '%.2f' %x

In [132]: frame.applymap(format)
Out[132]: 
            b      d      e
Utah     0.81   1.36  -0.60
Ohio     0.15   1.20  -0.15
Texas    1.04   0.41   1.40
Oregon  -0.55  -0.67  -0.46

之所以叫applymap,是因为Series有一个用于元素级函数的map方法:

In [133]: frame['e'].map(format)
Out[133]: 
Utah      -0.60
Ohio      -0.15
Texas      1.40
Oregon    -0.46
Name: e, dtype: object

排序和排名:

根据条件对数据集排序(sorting)也是一种重要的内置运算。

对行或列索引进行排序(按字典顺序),可使用sort_index方法,他将返回一个已排序的新对象:

In [134]: obj = Series(range(4), index=['d', 'a', 'b', 'c'])

In [135]: obj.sort_index()
Out[135]: 
a    1
b    2
c    3
d    0
dtype: int64

而对于DtaFrame,则可以根据任意一个轴上的索引进行排序:

In [136]: frame = DataFrame(np.arange(8).reshape((2, 4)), index=['three', 'one'], columns=['d', 'a', 'b', 'c'])

In [137]: frame.sort_index()
Out[137]: 
       d  a  b  c
one    4  5  6  7
three  0  1  2  3

In [138]: frame.sort_index(axis=1)
Out[138]: 
       a  b  c  d
three  1  2  3  0
one    5  6  7  4

数据默认是按升序排列的,也可以按降序排列:

In [140]: frame.sort_index(axis=1, ascending=False)
Out[140]: 
       d  c  b  a
three  0  3  2  1
one    4  7  6  5

若要对Series按值进行排序,sort_values方法:
排序时任何缺失值默认都会放到末尾:

In [141]: obj = Series([4, 7, -3, 2])
In [145]: obj.sort_values()
Out[145]: 
2   -3
3    2
0    4
1    7
dtype: int64

DataFrame上,根据一个或多个列中的值进行排序,将一个或多个列的名字传递给 by 选项:

In [146]: frame = DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
In [149]: frame.sort_values(by='b')
Out[149]: 
   a  b
2  0 -3
3  1  2
0  0  4
1  1  7

根据多个列排序,传入名称的列表即可:

In [150]: frame.sort_values(by=['a', 'b'])
Out[150]: 
   a  b
2  0 -3
0  0  4
3  1  2
1  1  7

排名(ranking)跟排序关系密切,且他会增设一个排名值(从1开始),它会根据某种规则破坏平级关系:

rank方法,默认情况下rank是通过“为各组分配一个平均排名”的方式破坏平级关系:

In [151]: obj = Series([7, -5, 7, 4, 2, 0, 4])

In [152]: obj.rank()
Out[152]: 
0    6.5
1    1.0
2    6.5
3    4.5
4    3.0
5    2.0
6    4.5
dtype: float64

也可以根据值在原数据中出现的顺序给出排名:
method = ‘average’/‘min’/‘max’/‘first’:

In [154]: obj.rank(method='first')
Out[154]: 
0    6.0
1    1.0
2    7.0
3    4.0
4    3.0
5    2.0
6    5.0
dtype: float64

In [155]: obj.rank(ascending=False, method='max')
Out[155]: 
0    2.0
1    7.0
2    2.0
3    4.0
4    5.0
5    6.0
6    4.0
dtype: float64

DataFrame可以在行或列上计算排名:

In [156]: frame = DataFrame({'b':[4.3, 7, -3, 2], 'a':[0, 1, 0, 1], 'c':[-2, 5, 8, -2.5]})

In [157]: frame
Out[157]: 
   a    b    c
0  0  4.3 -2.0
1  1  7.0  5.0
2  0 -3.0  8.0
3  1  2.0 -2.5

In [158]: frame.rank(axis=1)
Out[158]: 
     a    b    c
0  2.0  3.0  1.0
1  1.0  3.0  2.0
2  2.0  1.0  3.0
3  2.0  3.0  1.0

带有重复值的轴索引:

indexis_unique 属性可以告诉它的值是否唯一:

In [159]: obj = Series(range(5), index=['a', 'a', 'b', 'b', 'c'])

In [160]: obj
Out[160]: 
a    0
a    1
b    2
b    3
c    4
dtype: int64

In [161]: obj.index.is_unique
Out[161]: False
如果某个索引对应多个值,则返回一个Series;而对应单个值的,则返回一个标量值:
In [162]: obj['a']
Out[162]: 
a    0
a    1
dtype: int64

In [163]: obj['c']
Out[163]: 4

DataFrame的行进行索引时也是如此:

In [164]: df = DataFrame(np.random.randn(4, 3), index=['a', 'a', 'b', 'b'])

In [165]: df
Out[165]: 
          0         1         2
a -0.418238  0.816369 -1.476190
a  0.429244  1.026073 -1.226708
b -0.545915 -0.924662  2.804594
b  0.325699 -0.584846 -1.192865

In [166]: df.loc['b']
Out[166]: 
          0         1         2
b -0.545915 -0.924662  2.804594
b  0.325699 -0.584846 -1.192865
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容