pandas

作者: 昱灬岩 | 来源:发表于2016-05-08 14:32 被阅读2487次

    pandas 入门

    pandas 的数据结构介绍

    pandas 有两个重要的数据结构:Series和DataFrame。

    Series

    Series是一个一维的类似的数组对象,包含一个数组的数据(任何NumPy的数据类型)和一个与数组关联的数据标签,被叫做 索引 。

    obj = Series([4, 7, -5, 3])
    obj
    Ou:
    0 4
    1 7
    2 -5
    3 3
    
    # 如果没有给数据指定索引,一个包含整数0到 N-1 (这里N是数据的长度)的默认索引被创建。
    obj.values
    Out: array([ 4, 7, -5, 3])
     obj.index
    Out: Int64Index([0, 1, 2, 3])
    
    obj2 = Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
    obj2
    Out:
    d 4
    b 7
    a -5
    c 3
    

    Series是一个定长的有序的字典,因为它把索引和值映射起来了。

    'b' in obj2
    Out: True
    'e' in obj2
    Out: False
    

    可以通过传递一个 Python 字典来创建一个 Series:

    sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
    obj3 = Series(sdata)
    obj3
    Out:  # 结果是按照索引排序后的顺序
    Ohio 35000
    Oregon 16000
    Texas 71000
    Utah 5000113
    
    states = [‘California’, ‘Ohio’, ‘Oregon’, ‘Texas’]
    obj4 = Series(sdata, index=states)
    obj4 
    Out: 
    California NaN 
    Ohio 35000 
    Oregon 16000
    Texas 71000
    

    在这种情况下, sdata 中的3个值被放在了合适的位置,但因为没有发现对应于 ‘California’ 的值,就出现了 NaN (不是一个数),这在pandas中被用来标记数据缺失或 NA 值。我使用“missing”或“NA”来表示数度丢失。在pandas中用函数 isnull 和 notnull 来检测数据丢失:

    pd.isnull(obj4)  # 或者使用实例方法obj4.isnull()
    Out[26]:
    California True
    Ohio False
    Oregon False
    Texas False
    

    Series的一个重要的功能是:它在运算中会自动对齐不同索引的数据。

    obj3 + obj4
    Out:
    California NaN
    Ohio 70000
    Oregon 32000
    Texas 142000
    Utah NaN
    

    Series对象本身和它的索引都有一个 name 属性,它和pandas的其它一些关键功能整合在一起:

    obj4.name = 'population'
    obj4.index.name = 'state'
    obj4
    Out:
    state
    California NaN
    Ohio 35000
    Oregon 16000
    Texas 71000
    Name: population
    

    DataFrame

    一个Datarame表示一个表格,类似电子表格的数据结构,包含一个经过排序的列表集,它们没一个都可以有不同的类型值(数字,字符串,布尔等等)。

    有很多方法来构建一个DataFrame,但最常用的一个是用一个相等长度列表的字典或NumPy数组:

    data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
            'year': [2000, 2001, 2002, 2001, 2002],
            'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
    frame = DataFrame(data)
    frame
    Out:
      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
    

    如果你设定了一个列的顺序,DataFrame的列将会精确的按照你所传递的顺序排列;和Series一样,如果你传递了一个行,但不包括在 data 中,在结果中它会表示为NA值:

    frame2 = DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
       ....: index=['one', 'two', 'three', 'four', 'five'])
    frame2
    Out:
           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
    

    和Series一样,在DataFrame中的一列可以通过字典记法或属性来检索:

    frame2['state']  # 或是使用属性 frame2.state
    Out:
    one   Ohio
    two   Ohio 
    three Ohio 
    four  Nevada
    five  Nevada
    Name: state
    # 注意,返回的Series包含和DataFrame相同的索引,并它们的 name 属性也被正确的设置了。
    

    给一个不存在的列赋值,将会创建一个新的列。 像字典一样 del 关键字将会删除列。==索引DataFrame时返回的列是底层数据的一个视窗,而不是一个拷贝。因此,任何在Series上的就地修改都会影响DataFrame。列可以使用Series的 copy 函数来显式的拷贝。==

    另一种通用的数据形式是一个嵌套的字典的字典格式,如果被传递到DataFrame,它的外部键会被解释为列索引,内部键会被解释为行索引::

    pop = {'Nevada': {2001: 2.4, 2002: 2.9},
       ....: 'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
       
    frame3 = DataFrame(pop)
    frame3
    Out:
         Nevada Ohio
    2000    NaN  1.5
    2001    2.4  1.7
    2002    2.9  3.6
    

    可以输入给 DataFrame 构造器的数据

    类型 说明
    二维ndarray 一个数据矩阵,有可选的行标和列标
    数组,列表或元组的字典 每一个序列成为DataFrame中的一列。所有的序列必须有相同的长度。
    NumPy的结构/记录数组 和“数组字典”一样处理
    Series的字典 每一个值成为一列。如果没有明显的传递索引,将结合每一个Series的索引来形成结果的行索引。
    字典的字典 每一个内部的字典成为一列。和“Series的字典”一样,结合键值来形成行索引。
    字典或Series的列表 每一项成为DataFrame中的一列。结合字典键或Series索引形成DataFrame的列标。
    列表或元组的列表 和“二维ndarray”一样处理
    另一个DataFrame DataFrame的索引将被使用,除非传递另外一个
    NumPy伪装数组(MaskedArray) 除了掩码值在DataFrame中成为NA/丢失数据之外,其它的和“二维ndarray”一样

    DataFrame的 index 和 columns 有它们的 name,可以显示调用;跟 Series 一样,values 属性返回一个包含在 DataFrame 中的数据的二维 ndarray。

    索引对象

    pandas的索引对象用来保存坐标轴标签和其它元数据(如坐标轴名或名称)。构建一个Series或DataFrame时任何数组或其它序列标签在内部转化为索引:

    obj = Series(range(3), index=['a', 'b', 'c'])
    index = obj.index
    index
    Out: Index([a, b, c], dtype=object)
    index[1:]
    Out: Index([b, c], dtype=object)
    

    索引对象是不可变的,因此不能由用户改变;索引对象的不可变性非常重要,这样它可以在数据结构中结构中安全的共享。

    index[1] = 'd'  # 错误
    
    index = pd.Index(np.arange(3))
    obj2 = Series([1.5, -2.5, 0], index=index)
    obj2.index is index
    Out: True
    

    每个索引都有许多关于集合逻辑的方法和属性,且能够解决它所包含的数据的常见问题。

    索引方法和属性

    方法 说明
    append 链接额外的索引对象,产生一个新的索引
    diff 计算索引的差集
    intersection 计算交集
    union 计算并集
    isin 计算出一个布尔数组表示每一个值是否包含在所传递的集合里
    delete 计算删除位置i的元素的索引
    drop 计算删除所传递的值后的索引
    insert 计算在位置i插入元素后的索引
    is_monotonic 返回True,如果每一个元素都比它前面的元素大或相等
    is_unique 返回True,如果索引没有重复的值
    unique 计算索引的唯一值数组

    基本功能

    主要是操作 Series 和 DataFrame 中的数据的基本手段。

    重新索引

    pandas对象的一个关键的方法是 reindex ,创建一个适应新索引的新对象。

    obj = Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
    obj
    Out:
    d  4.5
    b  7.2
    a -5.3
    c  3.6
    

    在Series上调用 reindex 重排数据,使得它符合新的索引,如果那个索引的值不存在就引入缺失数据值:

    obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
    obj2
    Out:
    a -5.3
    b 7.2
    c 3.6
    d 4.5
    e NaN
    
    obj.reindex(['a', 'b', 'c', 'd', 'e'], fill_value=0)
    Out:
    a -5.3
    b 7.2
    c 3.6
    d 4.5
    e 0.0
    

    为了对时间序列这样的数据排序,当重建索引的时候可能想要对值进行内插或填充。 method 选项可以是你做到这一点,使用一个如 ffill 的方法来向前填充值:

    obj3 = Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
    obj3.reindex(range(6), method='ffill')
    Out:
    0   blue
    1   blue
    2 purple
    3 purple
    4 yellow
    5 yellow
    
    参数 描述
    ffill或pad 前向填充(或搬运)值
    bfill或backfill 后向填充(或搬运)值

    reindex 的(插值)method 选项

    参数 描述
    ffill或pad 前向填充(或搬运)值
    bfill或backfill 后向填充(或搬运)值

    对于DataFrame, reindex 可以改变(行)索引,列或两者。当只传入一个序列时,结果中的行被重新索引了:

    frame = DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'],
    ....: columns=['Ohio', 'Texas', 'California'])
    frame
    Out:
      Ohio Texas California
    a    0     1          2
    c    3     4          5
    d    6     7          8
    
    frame2 = frame.reindex(['a', 'b', 'c', 'd'])
    In [89]: frame2
    Out[89]:
      Ohio Texas California
    a    0     1          2
    b  NaN   NaN        NaN
    c    3     4          5
    d    6     7          8
    
    # 使用columns关键字指定列重新索引
    states = ['Texas', 'Utah', 'California']
    In [91]: frame.reindex(columns=states)
    Out[91]:
       Texas Utah California
    a      1  NaN          2
    c      4  NaN          5
    d      7  NaN          8
    

    一次可以对两个重新索引,可是插值只在行侧(0坐标轴)进行:

    frame.reindex(index=['a', 'b', 'c', 'd'], method='ffill',
       ....: columns=states)
    Out:
       Texas Utah California
    a      1  NaN          2
    b      1  NaN          2
    c      4  NaN          5
    d      7  NaN          8
    

    使用带标签索引的 ix 可以把重新索引做的更简单:

    frame.ix[['a', 'b', 'c', 'd'], states]
    Out:
      Texas Utah California
    a     1  NaN          2
    b   NaN  NaN        NaN
    c     4  NaN          5
    d     7  NaN          8
    

    reindex 函数的参数

    参数 说明
    index 作为索引的新序列。可以是索引实例或任何类似序列的Python数据结构。一个索引被完全使用,没有任何拷贝。
    method 插值(填充)方法,见上表。
    fill_value 代替重新索引时引入的缺失数据值
    limit 当前向或后向填充时,最大的填充间隙
    level 在多层索引上匹配简单索引,否则选择一个子集
    copy 如果新索引与就的相等则底层数据不会拷贝。默认为True(即始终拷贝)

    丢弃指定轴上的项

    从坐标轴删除一个多或多个条目是很容易的,如果你有一个索引数组或列表且没有这些条目,但是这可能需要一点修改和集合逻辑。 drop 方法将会返回一个新的对象并从坐标轴中删除指定的一个或多个值:

    obj = Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
    new_obj = obj.drop('c')
    new_obj
    Out:
    a   0
    b   1
    d   3
    e   4
    
    obj.drop(['d', 'c'])
    Out:
    a   0
    b   1
    e   4
    

    对于DataFrame,可以从任何坐标轴删除索引值。如 data.drop('a',axis = 0)。

    索引、选取和过滤

    Series索引( obj[...] )的工作原理类似与NumPy索引,除了可以使用Series的索引值,也可以仅使用整数来索引。使用索引来切片和正常的Python切片并不一样,会包含结束点。

    索引DataFrame来检索一个或多个列,可以使用一个单一值或一个序列:

    data = DataFrame(np.arange(16).reshape((4, 4)),
       .....: index=['Ohio', 'Colorado', 'Utah', 'New York'],
       .....: columns=['one', 'two', 'three', 'four'])
    data
    Out:
             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
    
    data['two']                 data[['three', 'one']]
    Out:                        Out:
    Ohio        1                          three one
    Colorado    5               Ohio           2   0
    Utah        9               Colorado       6   4
    New York   13               Utah          10   8
    Name: two                   New York      14  12
    

    可以通过切片或一个布尔数组来选择行:

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

    在索引中使用一个布尔DataFrame,例如通过纯量比较产生的:

    data < 5
    

    | 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
    索引字段 ix 可以从DataFrame选择一个行和列的子集,使用像NumPy的记法再加上轴标签。

    data.ix['Colorado',['two','three']]  # 或使用 data.ix['Colorado',[1,2]]
    Out:
    two     5
    three   6
    Name: Colorado
    
    data.ix[:'Utah','two']
    Out:
    Ohio        0
    Colorado    5
    Utah        9
    Name: two
    
    data.ix[data.three > 5, :3]
    Out:
             one two three
    Colorado   4   5     6
    Utah       8   9    10
    New York   12 13    14
    

    DataFrame 的索引选项

    类型 说明
    obj[val] 从DataFrame选择单一列或连续列。特殊情况下的便利:布尔数组(过滤行),切片(行切片),或布尔DataFrame(根据条件设置值)。
    obj.ix[val] 从DataFrame的行集选择单行
    obj.ix[:, val] 从列集选择单列
    obj.ix[val1, val2] 选择行和列
    reindex 方法 转换一个或多个轴到新的索引
    xs 方法 通过标签选择单行或单列到一个Series
    icol, irow 方法 通过整数位置,分别的选择单行或单列到一个Series
    get_value, set_value 方法 通过行和列标选择一个单值

    算术运算和数据对齐

    pandas的最重要的特性之一是在具有不同索引的对象间进行算术运算的行为。当把对象加起来时,如果有任何的索引对不相同的话,在结果中将会把各自的索引联合起来。内部数据对其,在索引不重合的地方引入了NA值。

    在算术方法中填充值

    在不同索引对象间的算术运算,当一个轴标签在另一个对象中找不到时,你可能想要填充一个特定的值,如0:

    df1 = DataFrame(np.arange(12).reshape((3,4)),columns=list('abcd'))
    df2 = DataFrame(np.arange(20).reshape((4,5)),columns=list('abcde'))
    df1 + df2
    

    把它们加起来导致在不重合的位置出现NA值:

    | a | b | c | d | e
    --- | --- | --- | --- | --- | ---
    0 | 0 | 2 | 4 | 6 | NaN
    1 | 9 | 11 | 13 | 15 | NaN
    2 | 18 | 20 | 22 | 24 | NaN
    3 | NaN | NaN | NaN | NaN | NaN

    在 df1 上使用 add 方法,我把 df2 传递给它并给 fill_value 赋了一个参数:

    df1.add(df2,fill_value=0)
    

    | a | b | c | d | e
    --- | --- | --- | --- | --- | ---
    0 | 0 | 2 | 4 | 6 | 4
    1 | 9 | 11 | 13 | 15 | 9
    2 | 18 | 20 | 22 | 24 | 14
    3 | 15 | 16 | 17 | 18 | 19

    灵活的算术方法

    方法 说明
    add 加法(+)
    sub 减法(-)
    div 除法(/)
    mul 乘法(*)

    DataFrame 和 Series 之间的运算

    DataFrame和Series间的算术运算Series的索引将匹配DataFrame的列,并在行上扩展。如果一个索引值在DataFrame的列和Series的索引里都找不着,对象将会从它们的联合重建索引。如果想在行上而不是列上进行扩展,你要使用一个算术方法。例如:

    frame = DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'),
                      index=['Utah', 'Ohio', 'Texas', 'Oregon'])
    
    frame
    

    | b | d | e
    --- | --- | --- | ---
    Utah | 0 | 1 | 2
    Ohio | 3 | 4 | 5
    Texas | 6 | 7 | 8
    Oregon | 9 | 10 | 11

    series = frame['d']
    frame.sub(series, axis=0)
    

    | b | d | e
    --- | --- | --- | ---
    Utah | -1 | 0 | 1
    Ohio | -1 | 0 | 1
    Texas | -1 | 0 | 1
    Oregon | -1 | 0 | 1

    函数应用和映射

    NumPy 的 ufuncs(元素级数组方法)也可以用于操作 pandas 对象:

    frame = DataFrame(np.random.randn(4, 3), columns=list('bde'),
                      index=['Utah', 'Ohio', 'Texas', 'Oregon'])
    frame
    Out:
            b           d           e
    Utah    -0.204708   0.478943    -0.519439
    Ohio    -0.555730   1.965781    1.393406
    Texas   0.092908    0.281746    0.769023
    Oregon  1.246435    1.007189    -1.296221
    
    np.abs(frame)  # frame 的元素的绝对值
    Out:
            b           d           e
    Utah    0.204708    0.478943    0.519439
    Ohio    0.555730    1.965781    1.393406
    Texas   0.092908    0.281746    0.769023
    Oregon  1.246435    1.007189    1.296221
    

    将函数应用到由各列或行所形成的一维数组上。DataFrame 的 apply 方法既可以实现此功能:

    f = lambda x: x.max() - x.min()
    frame.apply(f)
    Out:
        b    1.802165
        d    1.684034
        e    2.689627
        dtype: float64
    
    frame.apply(f, axis=1)
    Out:
    Utah      0.998382
    Ohio      2.521511
    Texas     0.676115
    Oregon    2.542656
    dtype: float64
    

    许多最为常见的数组统计方法都被实现成 DataFrame 方法(如 sum 和 mean),因此无须使用 apply 方法。

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

    def f(x):
        return Series([x.min(), x.max()], index=['min', 'max'])
    frame.apply(f)
    Out:
        b           d           e
    min -0.555730   0.281746    -1.296221
    max 1.246435    1.965781    1.393406
    

    此外,元素级的 Python 函数也是可以用的。要得到 frame 中各个浮点值的格式化字符串,使用 applymap (之所以叫 applymap ,是因为 Series 有一个用于应用元素级函数的 map 方法)即可:

    format = lambda x: '%.2f' % x
    frame.applymap(format)
    Out:
        b       d       e
    Utah    -0.20   0.48    -0.52
    Ohio    -0.56   1.97    1.39
    Texas   0.09    0.28    0.77
    Oregon  1.25    1.01    -1.30
    
    frame['e'].map(format)
    Out:
    Utah      -0.52
    Ohio       1.39
    Texas      0.77
    Oregon    -1.30
    Name: e, dtype: object
    

    排序和排名

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

    对 Series 用sort_index方法排序:

    obj = Series(range(4), index=['d', 'a', 'b', 'c'])
    obj.sort_index()
    Out:
    a    1
    b    2
    c    3
    d    0
    dtype: int64
    

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

    frame = DataFrame(np.arange(8).reshape((2, 4)), index=['three', 'one'],
                      columns=['d', 'a', 'b', 'c'])
    frame.sort_index()
    Out:
            d   a   b   c
    one 4   5   6   7
    three   0   1   2   3
    

    数据默认是生序排序的,但也可以将序排序:

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

    按值对 Series 进行排序,可以使用 order 方法:

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

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

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

    排名跟排序关系密切,且它会增设一个排名值(从1开始,一直到数组中有效数据的数量)。它跟 numpy.argsort 产生的间接排序索引差不多,只不过它可以根据某种规则破坏平级关系。

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

    obj = Series([7, -5, 7, 4, 2, 0, 4])
    obj.rank()
    Out:
    0    6.5
    1    1.0
    2    6.5
    3    4.5
    4    3.0
    5    2.0
    6    4.5
    dtype: float64
    

    也可以根据值在原数据中出现的顺序给出排名:

    obj.rank(method='first')
    Out:
    0    6
    1    1
    2    7
    3    4
    4    3
    5    2
    6    5
    dtype: float64
    

    排名时用于破坏平级关系的 method 选项

    method 说明
    average 默认:在相等分组中,为各个值分配平均排名
    min 使用整个分组的最小排名
    max 使用整个分组的最大排名
    first 按值在原始数据中的出现吮吸分配排名

    带有重复值的轴索引

    索引的 is_unique 属性可以查看索引值是否唯一。

    如果某个索引对应多个值,则返回一个 Series;而对应单个值得,则返回一个标量值。对 DataFrame 的行进行索引时也是如此。

    汇总和计算描述统计

    pandas 对象拥有一组常用的数学和统计方法。它们大部分都属于约简和汇总统计,用于从 Series 中提取单个值(如 sum 或 mean)或从 DataFrame 的行货列中提取一个 Series。跟对应的 Numpy 数组方法相比,它们都是基于没有缺失数据的假设而构建的。

    描述和汇总统计

    方法 说明
    count 非 NA 值的数量
    describe 针对 Series 或 DataFrame 的列计算汇总统计
    min , max 最小值和最大值
    argmin , argmax 最小值和最大值的索引位置(整数)
    idxmin , idxmax 最小值和最大值的索引值
    quantile 样本分位数(0 到 1)
    sum 求和
    mean 均值
    median 中位数
    mad 根据均值计算平均绝对离差
    var 方差
    std 标准差
    skew 样本值的偏度(三阶矩)
    kurt 样本值的峰度(四阶矩)
    cumsum 样本值的累计和
    cummin , cummax 样本值的累计最大值和累计最小值
    cumprod 样本值的累计积
    diff 计算一阶差分(对时间序列很有用)
    pct_change 计算百分数变化

    相关系数和协方差

    Series 的 corr 和 cov 方法用于计算两个 Series 中重叠的、非NA的、按索引对齐的值得相关系数和协方差。

    DataFrame 的 corr 和 cov 方法将以 DataFrame 的形式返回完整的相关系数或协方差矩阵。

    DataFrame 的 corrwith 方法可以计算其列或行跟另一个 Series 或 DataFrame 之间的相关系数。

    唯一值、值计算以及成员资格

    唯一值、值计数和成员资格方法

    方法 说明
    isin 计算一个表示“Series 各值是否包含于传入的值序列中”的布尔型数组
    unique 计算 Series 中的唯一值数组,按发现的顺序返回
    value_counts 返回一个 Series,其索引为唯一值,其值为计数,降序排列

    将pandas.value_counts 传给 DataFrame 的 apply 函数:

    data = DataFrame({'Qu1': [1, 3, 4, 3, 4],
                      'Qu2': [2, 3, 1, 2, 3],
                      'Qu3': [1, 5, 2, 4, 4]})
    data
    Out:
        Qu1 Qu2 Qu3
    0   1   2   1
    1   3   3   5
    2   4   1   2
    3   3   2   4
    4   4   3   4
    
    result = data.apply(pd.value_counts).fillna(0)
    result
    Out:
        Qu1 Qu2 Qu3
    1   1   1   1
    2   0   2   1
    3   2   2   0
    4   2   0   2
    5   0   0   1
    

    处理缺失数据

    NA 处理方法

    方法 说明
    dropna 根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过阀值调节对缺失值的容忍度
    fillna 用指定值或插值方法(如 ffill 或 bfill)填充缺失数据
    isnull 返回一个含有布尔值得对象,这些布尔值表示哪些值是缺失值,该对象的类型与源类型一样
    notnull isnull的否定式

    滤除缺失数据

    对于 DataFrame 对象,dropna 默认丢弃任何含有缺失值的行:

    data = DataFrame([[1., 6.5, 3.], [1., NA, NA],
                      [NA, NA, NA], [NA, 6.5, 3.]])
    cleaned = data.dropna()
    data
    Out:
        0   1   2
    0   1   6.5 3
    1   1   NaN NaN
    2   NaN NaN NaN
    3   NaN 6.5 3
    
    cleaned
    Out:
        0   1   2
    0   1   6.5 3
    

    传入 how = 'all' 将只丢弃全为 NA 的那些行:

    data.dropna(how='all')
    Out:
        0   1   2
    0   1   6.5 3
    1   1   NaN NaN
    3   NaN 6.5 3
    

    填充缺失数据

    fillna 方法是主要的填充函数。

    通过一个字典调用 fillna,可以实现对不同的列填充不同的值:

    df = DataFrame(np.random.randn(7, 3))
    df.ix[:4, 1] = NA; df.ix[:2, 2] = NA
    df
    Out:
        0   1   2
    0   0.274992    NaN NaN
    1   0.886429    NaN NaN
    2   1.669025    NaN NaN
    3   0.476985    NaN -1.021228
    4   -0.577087   NaN 0.302614
    5   0.523772    0.000940    1.343810
    6   -0.713544   -0.831154   -2.370232
    
    df.fillna({1: 0.5, 3: -1})
    Out:
        0   1   2
    0   0.274992    0.500000    NaN
    1   0.886429    0.500000    NaN
    2   1.669025    0.500000    NaN
    3   0.476985    0.500000    -1.021228
    4   -0.577087   0.500000    0.302614
    5   0.523772    0.000940    1.343810
    6   -0.713544   -0.831154   -2.370232
    

    fillna 函数的参数

    参数 说明
    value 用于填充缺失值的标量值或字典对象
    method 插值方式。如果函数调用时未指定其他参数的话,默认为“ffill”
    axis 待填充的轴,默认axis = 0
    inplace 修改调用者对象而不产生副本
    limit 可以连续填充的最大数量

    层次化索引

    层次化索引时 pandas 的一项重要功能,它是你能在一个轴上拥有多个索引级别。

    data = Series(np.random.randn(10),
                  index=[['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'd', 'd'],
                         [1, 2, 3, 1, 2, 3, 1, 2, 2, 3]])
    data
    Out:
    a  1   -0.204708
       2    0.478943
       3   -0.519439
    b  1   -0.555730
       2    1.965781
       3    1.393406
    c  1    0.092908
       2    0.281746
    d  2    0.769023
       3    1.246435
    dtype: float64
    
    data.index
    Out:
    MultiIndex(levels=[[u'a', u'b', u'c', u'd'], [1, 2, 3]],
               labels=[[0, 0, 0, 1, 1, 1, 2, 2, 3, 3], [0, 1, 2, 0, 1, 2, 0, 1, 1, 2]])
    

    层次化索引在数据重塑和基于分组的操作(如透视表生成)中扮演着重要角色。如 data 可以通过其 unstack 方法被重新安排到一个 DataFrame 中:

    data.unstack()
    Out:
        1           2           3
    a   -0.204708   0.478943    -0.519439
    b   -0.555730   1.965781    1.393406
    c   0.092908    0.281746    NaN
    d   NaN         0.769023    1.246435
    # unstack 的逆运算是 stack。
    

    对于一个 DataFrame,每条轴都可以有分层索引:

    frame = DataFrame(np.arange(12).reshape((4, 3)),
                      index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
                      columns=[['Ohio', 'Ohio', 'Colorado'],
                               ['Green', 'Red', 'Green']])
    frame.index.names = ['key1', 'key2']
    frame.columns.names = ['state', 'color']
    frame
    
    Out:
            state   Ohio    Colorado
            color   Green   Red Green
    key1    key2            
    a   1   0   1   2
            2   3   4   5
    b   1   6   7   8
            2   9   10  11
    

    重排分级顺序

    swaplevel 接受两个级别编号或名称,并返回一个互换了级别的新对象:

    frame.swaplevel('key1', 'key2')
    Out:
        state   Ohio        Colorado
            color   Green   Red Green
    key2    key1            
    1   a   0   1   2
    2   a   3   4   5
    1   b   6   7   8
    2   b   9   10  11
    

    sortlevel 根据单个级别中的值对数据进行排序。

    frame.swaplevel(0, 1).sortlevel(0)
    Out:
        state   Ohio    Colorado
            color   Green   Red Green
    key2    key1            
    1   a   0   1   2
            b   6   7   8
    2   a   3   4   5
            b   9   10  11
    

    根据级别汇总统计

    许多对 DataFrame 和 Series 的描述和汇总统计都有一个 level 选项,它用于指定某条周上求和的级别。

    frame.sum(level='color', axis=1)
    Out:
        color   Green   Red
    key1    key2        
    a   1   2   1
            2   8   4
    b   1   14  7
            2   20  10
    # 这其实利用了 pandas 的 groupby 功能。
    

    使用 DataFrame 的列

    DataFrame 的 set_index 函数可以将 DataFrame 的一个或多个列当做行索引来用,而 reset_index 函数则是将行索引变成 DataFrame 的列。

    frame = DataFrame({'a': range(7), 'b': range(7, 0, -1),
                       'c': ['one', 'one', 'one', 'two', 'two', 'two', 'two'],
                       'd': [0, 1, 2, 0, 1, 2, 3]})
    frame
    Out:
        a   b   c   d
    0   0   7   one 0
    1   1   6   one 1
    2   2   5   one 2
    3   3   4   two 0
    4   4   3   two 1
    5   5   2   two 2
    6   6   1   two 3
    
    frame2 = frame.set_index(['c', 'd'])  # 可以加入参数 drop=False 保留数据中的c、d列。
    frame2
    Out:
            a   b
    c   d       
    one 0   0   7
            1   1   6
            2   2   5
    two 0   3   4
            1   4   3
            2   5   2
            3   6   1
    
    frame2.reset_index()
    Out:
        c   d   a   b
    0   one 0   0   7
    1   one 1   1   6
    2   one 2   2   5
    3   two 0   3   4
    4   two 1   4   3
    5   two 2   5   2
    6   two 3   6   1
    

    其他有关 pandas 的话题

    整数索引

    操作由整数索引的 pandas 对象跟内置的 Python 数据结构(如列表和元组)在索引语义上有些不同。例如:

    ser = Series(np.arange(3.))
    ser[-1]
    

    ==会产生错误。==
    对于一个非整数索引,就没有问题。为了保持良好的一致性,尽量保持操作时面向标签的,同样包括用 ix 进行切片。如果需要可靠的、不考虑索引类型的、基于位置的索引,可以使用 Series 的 iloc 或 iat 方法和 DataFrame 的 irow 和 icol 方法:

    ser.iloc[-1]
    Out:
    2.0
    
    frame = DataFrame(np.arange(6).reshape((3, 2)), index=[2, 0, 1])
    frame.iloc[0]
    Out:
    0    0
    1    1
    Name: 2, dtype: int32
    

    面板数据

    pandas 有一个 Panel 数据结构,可以将其看作一个三维版的 DataFrame。pandas 的大部分开发工作都集中在表格型数据上,所以这些事数据更常见。

    相关文章

      网友评论

        本文标题:pandas

        本文链接:https://www.haomeiwen.com/subject/kipsrttx.html