pandas0.24.1文档3.3 基础功能(三)

作者: Lykit01 | 来源:发表于2019-04-09 23:33 被阅读6次

    目录:
    1 0.24.1版本新特性
    2 安装
    3马上开始
    3.1 pandas概况
    3.2 十分钟上手pandas
    3.3 基础功能(一)
    3.3 基础功能(二)
    3.3基础功能(三)

    3.3.11 排序

    pandas支持三种排序方式:通过index标签、通过每列的值和结合两者来排序。

    3.3.11.1 通过index

    通过index来给pandas对象排序,需要用到Series.sort_index()和DataFrame.sort_index()方法。

    In [295]: df = pd.DataFrame({
       .....:     'one': pd.Series(np.random.randn(3), index=['a', 'b', 'c']),
       .....:     'two': pd.Series(np.random.randn(4), index=['a', 'b', 'c', 'd']),
       .....:     'three': pd.Series(np.random.randn(3), index=['b', 'c', 'd'])})
       .....: 
    
    In [296]: unsorted_df = df.reindex(index=['a', 'd', 'c', 'b'],
       .....:                          columns=['three', 'two', 'one'])
       .....: 
    
    In [297]: unsorted_df
    Out[297]: 
          three       two       one
    a       NaN -0.867293  0.050162
    d  1.215473 -0.051744       NaN
    c -0.421091 -0.712097  0.953102
    b  1.205223  0.632624 -1.534113
    
    # DataFrame
    In [298]: unsorted_df.sort_index()
    Out[298]: 
          three       two       one
    a       NaN -0.867293  0.050162
    b  1.205223  0.632624 -1.534113
    c -0.421091 -0.712097  0.953102
    d  1.215473 -0.051744       NaN
    
    In [299]: unsorted_df.sort_index(ascending=False)
    Out[299]: 
          three       two       one
    d  1.215473 -0.051744       NaN
    c -0.421091 -0.712097  0.953102
    b  1.205223  0.632624 -1.534113
    a       NaN -0.867293  0.050162
    
    In [300]: unsorted_df.sort_index(axis=1)
    Out[300]: 
            one     three       two
    a  0.050162       NaN -0.867293
    d       NaN  1.215473 -0.051744
    c  0.953102 -0.421091 -0.712097
    b -1.534113  1.205223  0.632624
    
    # Series
    In [301]: unsorted_df['three'].sort_index()
    Out[301]: 
    a         NaN
    b    1.205223
    c   -0.421091
    d    1.215473
    Name: three, dtype: float64
    
    3.3.11.2 通过值

    对于Series可以通过Series.sort_values()方法来排序。对于DataFrame可以通过DataFrame.sort_values()方法用列或行的值来进行排序。DataFrame.sort_values()可选的by参数可以用来指定使用一或多列来用作排序的标准。

    In [302]: df1 = pd.DataFrame({'one': [2, 1, 1, 1],
       .....:                     'two': [1, 3, 2, 4],
       .....:                     'three': [5, 4, 3, 2]})
       .....: 
    
    In [303]: df1.sort_values(by='two')
    Out[303]: 
       one  two  three
    0    2    1      5
    2    1    2      3
    1    1    3      4
    3    1    4      2
    

    by参数可以赋予多个列名组成的列表,比如:

    In [304]: df1[['one', 'two', 'three']].sort_values(by=['one', 'two'])
    Out[304]: 
       one  two  three
    2    1    2      3
    1    1    3      4
    3    1    4      2
    0    2    1      5
    

    这些方法还通过na_position参数来对空值做特殊处理:

    In [305]: s[2] = np.nan
    
    In [306]: s.sort_values()
    Out[306]: 
    0       A
    3    Aaba
    1       B
    4    Baca
    6    CABA
    8     cat
    7     dog
    2     NaN
    5     NaN
    dtype: object
    
    In [307]: s.sort_values(na_position='first')
    Out[307]: 
    2     NaN
    5     NaN
    0       A
    3    Aaba
    1       B
    4    Baca
    6    CABA
    8     cat
    7     dog
    dtype: object
    
    3.3.11.3 通过index和值

    这是0.23.0版本的新特性
    DataFrame.sort_values()传给by参数的字符串可能是列名,也可能是index名。

    # Build MultiIndex
    In [308]: idx = pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('a', 2),
       .....:                                 ('b', 2), ('b', 1), ('b', 1)])
       .....: 
    
    In [309]: idx.names = ['first', 'second']
    
    # Build DataFrame
    In [310]: df_multi = pd.DataFrame({'A': np.arange(6, 0, -1)},
       .....:                         index=idx)
       .....: 
    
    In [311]: df_multi
    Out[311]: 
                  A
    first second   
    a     1       6
          2       5
          2       4
    b     2       3
          1       2
          1       1
    

    下面通过'second'(index)和'A'(column)来排序:

    In [312]: df_multi.sort_values(by=['second', 'A'])
    Out[312]: 
                  A
    first second   
    b     1       1
          1       2
    a     1       6
    b     2       3
    a     2       4
          2       5
    

    注意: 如果一个字符串同时和列名和index名相同,pandas会发出警告,但还是会继续程序并优先匹配列名。但是在未来版本中这种同时匹配的情况会直接出现歧义错误。

    3.3.11.4 searchsorted方法

    Series有searchsorted()方法,用法和numpy.ndarray.searchsorted()类似。

    In [313]: ser = pd.Series([1, 2, 3])
    
    In [314]: ser.searchsorted([0, 3])
    Out[314]: array([0, 2])
    
    In [315]: ser.searchsorted([0, 4])
    Out[315]: array([0, 3])
    
    In [316]: ser.searchsorted([1, 3], side='right')
    Out[316]: array([1, 3])
    
    In [317]: ser.searchsorted([1, 3], side='left')
    Out[317]: array([0, 2])
    
    In [318]: ser = pd.Series([3, 1, 2])
    
    In [319]: ser.searchsorted([0, 3], sorter=np.argsort(ser))
    Out[319]: array([0, 2])
    

    searchsorted()方法的参数是:searchsorted(a,v)或a.searchsorted(v),原理是在a中检索v所处的位置,默认从左开始检索。

    3.3.11.5 最小/最大的值

    Series的nsmallest()nlargest()两个方法能返回最小和最大的n个值。对于非常大型的Series,相比先排序再使用head(n)取前n个数,使用这两个方法会快很多。

    In [320]: s = pd.Series(np.random.permutation(10))
    
    In [321]: s
    Out[321]: 
    0    5
    1    3
    2    2
    3    0
    4    7
    5    6
    6    9
    7    1
    8    4
    9    8
    dtype: int64
    
    In [322]: s.sort_values()
    Out[322]: 
    3    0
    7    1
    2    2
    1    3
    8    4
    0    5
    5    6
    4    7
    9    8
    6    9
    dtype: int64
    
    In [323]: s.nsmallest(3)
    Out[323]: 
    3    0
    7    1
    2    2
    dtype: int64
    
    In [324]: s.nlargest(3)
    Out[324]: 
    6    9
    9    8
    4    7
    dtype: int64
    

    DataFrame也有nlargest和nsmallest这两个方法。

    In [325]: df = pd.DataFrame({'a': [-2, -1, 1, 10, 8, 11, -1],
       .....:                    'b': list('abdceff'),
       .....:                    'c': [1.0, 2.0, 4.0, 3.2, np.nan, 3.0, 4.0]})
       .....: 
    
    In [326]: df.nlargest(3, 'a')
    Out[326]: 
        a  b    c
    5  11  f  3.0
    3  10  c  3.2
    4   8  e  NaN
    
    In [327]: df.nlargest(5, ['a', 'c'])
    Out[327]: 
        a  b    c
    5  11  f  3.0
    3  10  c  3.2
    4   8  e  NaN
    2   1  d  4.0
    6  -1  f  4.0
    
    In [328]: df.nsmallest(3, 'a')
    Out[328]: 
       a  b    c
    0 -2  a  1.0
    1 -1  b  2.0
    6 -1  f  4.0
    
    In [329]: df.nsmallest(5, ['a', 'c'])
    Out[329]: 
       a  b    c
    0 -2  a  1.0
    1 -1  b  2.0
    6 -1  f  4.0
    2  1  d  4.0
    4  8  e  NaN
    
    3.3.11.6 对有多重索引的列排序

    当列有多重索引时,对列的值进行排序时一定要把赋给by参数的列名写完整。(要细到最低级的列名。)

    In [330]: df1.columns = pd.MultiIndex.from_tuples([('a', 'one'),
       .....:                                          ('a', 'two'),
       .....:                                          ('b', 'three')])
       .....: 
    
    In [331]: df1.sort_values(by=('a', 'two'))
    Out[331]: 
        a         b
      one two three
    0   2   1     5
    2   1   2     3
    1   1   3     4
    3   1   4     2
    

    3.3.12 复制

    pandas对象的copy()方法复制底层数据(尽管不是轴索引,因为它们是不可变的)并返回一个新对象。注意很少有情况需要复制对象。 比如,只有几个方法可以原地修改DataFrame的值:

    • 插入、删除或修改一列数据
    • 对index或column的属性赋值
    • 对于同质的数据,通过属性或高级索引直接修可以明确地说,没有pandas方法会产生修改数据的副作用。几乎所有方法都返回一个新对象,而原数据保持原封不动。如果数据被修改了,那一定是因为用户“明显地”修改了数据。

    3.3.13 数据类型(dtypes)

    在大多数情况下,pandas在Series或DataFrame单个的列中使用NumPy的数组和dtypes。NumPy支持float、int、bool、timedelta64[ns]和datetime64[ns]。(注意NumPy并不支持标有时区的时间格式)
    pandas和第三方库对NumPy的数据类型系统在一些地方做了扩展。这部分描述了pandas在内部做了哪些扩展。如果你想做自己的扩展并且能在pandas中能使用,请看扩展类型。第三方加入的扩展请看扩展数据类型
    下表列出了所有的pandas扩展类型。请看每种类型的具体文档描述。

    数据种类 数据类型 标量 数组 文档
    标有时区的时间 DatetimeTZDtype 时间戳 array.DatatimeArray 时区处理
    Categorical CategoricalDtype (none) Categorical Categorical Data
    时间段 PeriodDtype Period arrays.PeriodArray 时间段表示
    稀疏数据 SparseDtype (none) [arrays.SparseArray] 稀疏数据结构
    间隔 IntervalDtype Interval arrays.IntervalArray IntervalIndex
    可为空的整数 Int64Dtype等等 (none) arrays.IntegerArray Nullable Integer Data Type

    pandas使用object这种数据类型来储存字符串。
    最后,可以使用object数据类型储存任意对象,但是应该尽可能避免这么做(为了性能和与其他库和方法的互操作性等原因。请看对象转换)。
    DataFrame的dtypes属性可以很方便地返回一个包含每列数据类型的Series。

    In [332]: dft = pd.DataFrame({'A': np.random.rand(3),
       .....:                     'B': 1,
       .....:                     'C': 'foo',
       .....:                     'D': pd.Timestamp('20010102'),
       .....:                     'E': pd.Series([1.0] * 3).astype('float32'),
       .....:                     'F': False,
       .....:                     'G': pd.Series([1] * 3, dtype='int8')})
       .....: 
    
    In [333]: dft
    Out[333]: 
              A  B    C          D    E      F  G
    0  0.278831  1  foo 2001-01-02  1.0  False  1
    1  0.242124  1  foo 2001-01-02  1.0  False  1
    2  0.078031  1  foo 2001-01-02  1.0  False  1
    
    In [334]: dft.dtypes
    Out[334]: 
    A           float64
    B             int64
    C            object
    D    datetime64[ns]
    E           float32
    F              bool
    G              int8
    dtype: object
    

    对于Series对象,用dtype属性。

    In [335]: dft['A'].dtype
    Out[335]: dtype('float64')
    

    如果一个pandas对象的一个列包含多种dtypes,那么这列的dtype将会适应这列的所有数据类型。(通常是用object类型。)

    # these ints are coerced to floats
    In [336]: pd.Series([1, 2, 3, 4, 5, 6.])
    Out[336]: 
    0    1.0
    1    2.0
    2    3.0
    3    4.0
    4    5.0
    5    6.0
    dtype: float64
    
    # string data forces an ``object`` dtype
    In [337]: pd.Series([1, 2, 3, 6., 'foo'])
    Out[337]: 
    0      1
    1      2
    2      3
    3      6
    4    foo
    dtype: object
    

    一个DataFrame中使用每个数据类型的列数可以调用get_dtype_counts()来统计。

    In [338]: dft.get_dtype_counts()
    Out[338]: 
    float64           1
    float32           1
    int64             1
    int8              1
    datetime64[ns]    1
    bool              1
    object            1
    dtype: int64
    

    数字dtypes将传播,并且可以在DataFrame共存。如果传递了一个dtype(直接通过dtype关键字、传递的ndarray或传递的Series),那么它将保留在DataFrame操作中。此外,不同的数字dtypes不会组合在一起。下面的例子将让您体验一下。

    In [339]: df1 = pd.DataFrame(np.random.randn(8, 1), columns=['A'], dtype='float32')
    
    In [340]: df1
    Out[340]: 
              A
    0 -1.641339
    1 -0.314062
    2 -0.679206
    3  1.178243
    4  0.181790
    5 -2.044248
    6  1.151282
    7 -1.641398
    
    In [341]: df1.dtypes
    Out[341]: 
    A    float32
    dtype: object
    
    In [342]: df2 = pd.DataFrame({'A': pd.Series(np.random.randn(8), dtype='float16'),
       .....:                     'B': pd.Series(np.random.randn(8)),
       .....:                     'C': pd.Series(np.array(np.random.randn(8),
       .....:                                             dtype='uint8'))})
       .....: 
    
    In [343]: df2
    Out[343]: 
              A         B    C
    0  0.130737 -1.143729    1
    1  0.289551  2.787500    0
    2  0.590820 -0.708143  254
    3 -0.020142 -1.512388    0
    4 -1.048828 -0.243145    1
    5 -0.808105 -0.650992    0
    6  1.373047  2.090108    0
    7 -0.254395  0.433098    0
    
    In [344]: df2.dtypes
    Out[344]: 
    A    float16
    B    float64
    C      uint8
    dtype: object
    
    3.3.13.1 默认设置

    默认情况下,整数都是int64类型,浮点数都是float64型,与平台无关(不论32位或64位系统)。下面的操作将会导致int64 dtypes。

    In [345]: pd.DataFrame([1, 2], columns=['a']).dtypes
    Out[345]: 
    a    int64
    dtype: object
    
    In [346]: pd.DataFrame({'a': [1, 2]}).dtypes
    Out[346]: 
    a    int64
    dtype: object
    
    In [347]: pd.DataFrame({'a': 1}, index=list(range(2))).dtypes
    Out[347]: 
    a    int64
    dtype: object
    

    注意在创建数组时,NumPy会依照平台选择合适的数据类型。下面在32位平台的操作将会产生int32数据类型。

    In [348]: frame = pd.DataFrame(np.array([1, 2]))
    
    3.3.13.2 数据类型升级

    当与其他类型的数据结合时,数据类型可能会升级,这意味着它们会从当前类型向上升级(例如从int到float)。

    In [349]: df3 = df1.reindex_like(df2).fillna(value=0.0) + df2
    
    In [350]: df3
    Out[350]: 
              A         B      C
    0 -1.510602 -1.143729    1.0
    1 -0.024511  2.787500    0.0
    2 -0.088385 -0.708143  254.0
    3  1.158101 -1.512388    0.0
    4 -0.867039 -0.243145    1.0
    5 -2.852354 -0.650992    0.0
    6  2.524329  2.090108    0.0
    7 -1.895793  0.433098    0.0
    
    In [351]: df3.dtypes
    Out[351]: 
    A    float32
    B    float64
    C    float64
    dtype: object
    

    dataframe.to_numpy()将返回数据类型的较低的公分母,这种类型可以容纳生成的同质的numpy数组中所有的数据类型。这会迫使一些类型升级。

    In [352]: df3.to_numpy().dtype
    Out[352]: dtype('float64')
    
    3.3.13.3 astype方法

    你可以用astype()方法对数据类型进行转换。这些操作默认返回一个副本,即使原数据类型并没有改变。(传递参数copy=False可以改变这种操作。)此外,如果astype操作不合法,程序会报错。
    类型升级操作经常是根据numpy规则的。如果操作包括两个不同的数据类型,其中更通常的类型将被用作操作的结果。

    In [353]: df3
    Out[353]: 
              A         B      C
    0 -1.510602 -1.143729    1.0
    1 -0.024511  2.787500    0.0
    2 -0.088385 -0.708143  254.0
    3  1.158101 -1.512388    0.0
    4 -0.867039 -0.243145    1.0
    5 -2.852354 -0.650992    0.0
    6  2.524329  2.090108    0.0
    7 -1.895793  0.433098    0.0
    
    In [354]: df3.dtypes
    Out[354]: 
    A    float32
    B    float64
    C    float64
    dtype: object
    
    # conversion of dtypes
    In [355]: df3.astype('float32').dtypes
    Out[355]: 
    A    float32
    B    float32
    C    float32
    dtype: object
    

    使用astype()可以将部分列转换到指定的类型。

    In [356]: dft = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [7, 8, 9]})
    
    In [357]: dft[['a', 'b']] = dft[['a', 'b']].astype(np.uint8)
    
    In [358]: dft
    Out[358]: 
       a  b  c
    0  1  4  7
    1  2  5  8
    2  3  6  9
    
    In [359]: dft.dtypes
    Out[359]: 
    a    uint8
    b    uint8
    c    int64
    dtype: object
    

    0.19.0版本新特性
    给astype()传递一个字典参数,能将指定的列转换到指定的数据类型。

    In [360]: dft1 = pd.DataFrame({'a': [1, 0, 1], 'b': [4, 5, 6], 'c': [7, 8, 9]})
    
    In [361]: dft1 = dft1.astype({'a': np.bool, 'c': np.float64})
    
    In [362]: dft1
    Out[362]: 
           a  b    c
    0   True  4  7.0
    1  False  5  8.0
    2   True  6  9.0
    
    In [363]: dft1.dtypes
    Out[363]: 
    a       bool
    b      int64
    c    float64
    dtype: object
    

    注意: 当试图使用astype()和loc()将一部分列转换到指定的类型时,可能会发生类型升级。loc()会试着去适应我们赋给当前数据类型鄂内容,而[]将用从右侧获取数据类型的内容覆盖这些内容。因此,下面的我代码会产生意外的结果。

    In [364]: dft = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [7, 8, 9]})
    
    In [365]: dft.loc[:, ['a', 'b']].astype(np.uint8).dtypes
    Out[365]: 
    a    uint8
    b    uint8
    dtype: object
    
    In [366]: dft.loc[:, ['a', 'b']] = dft.loc[:, ['a', 'b']].astype(np.uint8)
    
    In [367]: dft.dtypes
    Out[367]: 
    a    int64
    b    int64
    c    int64
    dtype: object
    
    3.3.13.4 对象转换

    pandas提供了很多对象转换的函数。在一些情况下,数据本身是正确的类型,但是被储存在了object类型的数组中,DataFrame.infer_objects()和Series.infer_objects()方法能自动转换到正确的类型。

    In [368]: import datetime
    
    In [369]: df = pd.DataFrame([[1, 2],
       .....:                    ['a', 'b'],
       .....:                    [datetime.datetime(2016, 3, 2),
       .....:                     datetime.datetime(2016, 3, 2)]])
       .....: 
    
    In [370]: df = df.T
    
    In [371]: df
    Out[371]: 
       0  1                    2
    0  1  a  2016-03-02 00:00:00
    1  2  b  2016-03-02 00:00:00
    
    In [372]: df.dtypes
    Out[372]: 
    0    object
    1    object
    2    object
    dtype: object
    

    .T会将行、列进行转换。我们来看看原数据:

    0 1
    0 1 2
    1 a b
    2 2016-03-02 00:00:00 2016-03-02 00:00:00

    数据类型:

    0    object
    1    object
    dtype: object
    

    原数据将所有列储存为object类型,现在行、列转换了,infer_objects将能推断出正确的数据结构。

    In [373]: df.infer_objects().dtypes
    Out[373]: 
    0             int64
    1            object
    2    datetime64[ns]
    dtype: object
    

    可以用下面的函数将一维的object类型数组转换为指定的类型:

    • to_numeric()(转换为数值型的dtypes)
    In [374]: m = ['1.1', 2, 3]
    
    In [375]: pd.to_numeric(m)
    Out[375]: array([ 1.1,  2. ,  3. ])
    
    • to_datetime()(转换为时间对象)
    In [376]: import datetime
    
    In [377]: m = ['2016-07-09', datetime.datetime(2016, 3, 2)]
    
    In [378]: pd.to_datetime(m)
    Out[378]: DatetimeIndex(['2016-07-09', '2016-03-02'], dtype='datetime64[ns]', freq=None)
    
    • to_timedelta()(转换为时间段对象)
    In [379]: m = ['5us', pd.Timedelta('1day')]
    
    In [380]: pd.to_timedelta(m)
    Out[380]: TimedeltaIndex(['0 days 00:00:00.000005', '1 days 00:00:00'], dtype='timedelta64[ns]', freq=None)
    

    如果要进行强制转换,我们可以传递一个errors参数,如果数据中的某些元素不能被强制转换,可以用这个参数指导pandas具体怎么做。默认情况下,指定errors='raise',意味着在转换过程中只有遇到错误就会报错。但是,如果设定errors='coerce',这些错误将被忽略,并且pandas将把有问题的元素转换成pd.NaT(如果转换目标是datetime或timedelta)或者np.nan(如果转换对象是数值型的)。如果你想呈现的数据中大部分都是你想要的数据类型(比如数值、时间等),只有少数几个不符合的元素混杂其中,用这个参数将这几个处理成缺失值很有用。

    In [381]: import datetime
    
    In [382]: m = ['apple', datetime.datetime(2016, 3, 2)]
    
    In [383]: pd.to_datetime(m, errors='coerce')
    Out[383]: DatetimeIndex(['NaT', '2016-03-02'], dtype='datetime64[ns]', freq=None)
    
    In [384]: m = ['apple', 2, 3]
    
    In [385]: pd.to_numeric(m, errors='coerce')
    Out[385]: array([ nan,   2.,   3.])
    
    In [386]: m = ['apple', pd.Timedelta('1day')]
    
    In [387]: pd.to_timedelta(m, errors='coerce')
    Out[387]: TimedeltaIndex([NaT, '1 days'], dtype='timedelta64[ns]', freq=None)
    

    errors参数还有第三个可选的值errors='ignore',如果在转换为所需数据类型时遇到任何错误,它只返回传入的数据:

    [388]: import datetime
    
    In [389]: m = ['apple', datetime.datetime(2016, 3, 2)]
    
    In [390]: pd.to_datetime(m, errors='ignore')
    Out[390]: Index(['apple', 2016-03-02 00:00:00], dtype='object')
    
    In [391]: m = ['apple', 2, 3]
    
    In [392]: pd.to_numeric(m, errors='ignore')
    Out[392]: array(['apple', 2, 3], dtype=object)
    
    In [393]: m = ['apple', pd.Timedelta('1day')]
    
    In [394]: pd.to_timedelta(m, errors='ignore')
    Out[394]: array(['apple', Timedelta('1 days 00:00:00')], dtype=object)
    

    除了类型转换之外,to_numeric()还提供了一个downcast参数,这个参数可以选择是否将新产生的或已经存在的数值型数据“降级”到一个更小的数据类型,这样可以省很多内存。

    In [395]: m = ['1', 2, 3]
    
    In [396]: pd.to_numeric(m, downcast='integer')   # smallest signed int dtype
    Out[396]: array([1, 2, 3], dtype=int8)
    
    In [397]: pd.to_numeric(m, downcast='signed')    # same as 'integer'
    Out[397]: array([1, 2, 3], dtype=int8)
    
    In [398]: pd.to_numeric(m, downcast='unsigned')  # smallest unsigned int dtype
    Out[398]: array([1, 2, 3], dtype=uint8)
    
    In [399]: pd.to_numeric(m, downcast='float')     # smallest float dtype
    Out[399]: array([ 1.,  2.,  3.], dtype=float32)
    

    上面这些方法只能对一维的数组、列表或标量运用,他们不能直接作用于多维的对象,比如DataFrame。但是,用apply()方法,我们能将这些方法对每个列进行应用。

    In [400]: import datetime
    
    In [401]: df = pd.DataFrame([
       .....:     ['2016-07-09', datetime.datetime(2016, 3, 2)]] * 2, dtype='O')
       .....: 
    
    In [402]: df
    Out[402]: 
                0                    1
    0  2016-07-09  2016-03-02 00:00:00
    1  2016-07-09  2016-03-02 00:00:00
    
    In [403]: df.apply(pd.to_datetime)
    Out[403]: 
               0          1
    0 2016-07-09 2016-03-02
    1 2016-07-09 2016-03-02
    
    In [404]: df = pd.DataFrame([['1.1', 2, 3]] * 2, dtype='O')
    
    In [405]: df
    Out[405]: 
         0  1  2
    0  1.1  2  3
    1  1.1  2  3
    
    In [406]: df.apply(pd.to_numeric)
    Out[406]: 
         0  1  2
    0  1.1  2  3
    1  1.1  2  3
    
    In [407]: df = pd.DataFrame([['5us', pd.Timedelta('1day')]] * 2, dtype='O')
    
    In [408]: df
    Out[408]: 
         0                1
    0  5us  1 days 00:00:00
    1  5us  1 days 00:00:00
    
    In [409]: df.apply(pd.to_timedelta)
    Out[409]: 
                    0      1
    0 00:00:00.000005 1 days
    1 00:00:00.000005 1 days
    
    3.3.13.5 gotchas

    对整数类型的数据进行选择操作很容易把它们变成浮点数类型。只有在一些没有空值的例子中,输入的数据的dtype会被保留。请看整数空值支持

    In [410]: dfi = df3.astype('int32')
    
    In [411]: dfi['E'] = 1
    
    In [412]: dfi
    Out[412]: 
       A  B    C  E
    0 -1 -1    1  1
    1  0  2    0  1
    2  0  0  254  1
    3  1 -1    0  1
    4  0  0    1  1
    5 -2  0    0  1
    6  2  2    0  1
    7 -1  0    0  1
    
    In [413]: dfi.dtypes
    Out[413]: 
    A    int32
    B    int32
    C    int32
    E    int64
    dtype: object
    
    In [414]: casted = dfi[dfi > 0]
    
    In [415]: casted
    Out[415]: 
         A    B      C  E
    0  NaN  NaN    1.0  1
    1  NaN  2.0    NaN  1
    2  NaN  NaN  254.0  1
    3  1.0  NaN    NaN  1
    4  NaN  NaN    1.0  1
    5  NaN  NaN    NaN  1
    6  2.0  2.0    NaN  1
    7  NaN  NaN    NaN  1
    
    In [416]: casted.dtypes
    Out[416]: 
    A    float64
    B    float64
    C    float64
    E      int64
    dtype: object
    

    不过,float类型是不会变的。

    In [417]: dfa = df3.copy()
    
    In [418]: dfa['A'] = dfa['A'].astype('float32')
    
    In [419]: dfa.dtypes
    Out[419]: 
    A    float32
    B    float64
    C    float64
    dtype: object
    
    In [420]: casted = dfa[df2 > 0]
    
    In [421]: casted
    Out[421]: 
              A         B      C
    0 -1.510602       NaN    1.0
    1 -0.024511  2.787500    NaN
    2 -0.088385       NaN  254.0
    3       NaN       NaN    NaN
    4       NaN       NaN    1.0
    5       NaN       NaN    NaN
    6  2.524329  2.090108    NaN
    7       NaN  0.433098    NaN
    
    In [422]: casted.dtypes
    Out[422]: 
    A    float32
    B    float64
    C    float64
    dtype: object
    

    3.3.14 基于数据类型(dtype)选择列

    select_dtypes()方法基于列的类型来选择列。
    首先,我们创建一个有各种不同类型的列的DataFrame:

    In [423]: df = pd.DataFrame({'string': list('abc'),
       .....:                    'int64': list(range(1, 4)),
       .....:                    'uint8': np.arange(3, 6).astype('u1'),
       .....:                    'float64': np.arange(4.0, 7.0),
       .....:                    'bool1': [True, False, True],
       .....:                    'bool2': [False, True, False],
       .....:                    'dates': pd.date_range('now', periods=3),
       .....:                    'category': pd.Series(list("ABC")).astype('category')})
       .....: 
    
    In [424]: df['tdeltas'] = df.dates.diff()
    
    In [425]: df['uint64'] = np.arange(3, 6).astype('u8')
    
    In [426]: df['other_dates'] = pd.date_range('20130101', periods=3)
    
    In [427]: df['tz_aware_dates'] = pd.date_range('20130101', periods=3, tz='US/Eastern')
    
    In [428]: df
    Out[428]: 
      string  int64  uint8  float64  bool1  bool2                      dates category tdeltas  uint64 other_dates            tz_aware_dates
    0      a      1      3      4.0   True  False 2019-03-12 22:38:38.692567        A     NaT       3  2013-01-01 2013-01-01 00:00:00-05:00
    1      b      2      4      5.0  False   True 2019-03-13 22:38:38.692567        B  1 days       4  2013-01-02 2013-01-02 00:00:00-05:00
    2      c      3      5      6.0   True  False 2019-03-14 22:38:38.692567        C  1 days       5  2013-01-03 2013-01-03 00:00:00-05:00
    

    我们来看看数据类型:

    In [429]: df.dtypes
    Out[429]: 
    string                                object
    int64                                  int64
    uint8                                  uint8
    float64                              float64
    bool1                                   bool
    bool2                                   bool
    dates                         datetime64[ns]
    category                            category
    tdeltas                      timedelta64[ns]
    uint64                                uint64
    other_dates                   datetime64[ns]
    tz_aware_dates    datetime64[ns, US/Eastern]
    dtype: object
    

    select_dtypes()有两个参数include和exclude,include能够选择指定的类型的列,exculde能够选择排除指定的类型之外的列。
    举个例子,我们要选择bool型的列:

    In [430]: df.select_dtypes(include=[bool])
    Out[430]: 
       bool1  bool2
    0   True  False
    1  False   True
    2   True  False
    

    你也可以传递NumPy数据类型层次结构中的dtype的字符串名:

    In [431]: df.select_dtypes(include=['bool'])
    Out[431]: 
       bool1  bool2
    0   True  False
    1  False   True
    2   True  False
    

    select_dtypes()也可以使用泛型类型。
    比如,在排除无符号整数的同时选择所有数值列和布尔列:

    In [432]: df.select_dtypes(include=['number', 'bool'], exclude=['unsignedinteger'])
    Out[432]: 
       int64  float64  bool1  bool2 tdeltas
    0      1      4.0   True  False     NaT
    1      2      5.0  False   True  1 days
    2      3      6.0   True  False  1 days
    

    如果要选择字符串类型的列,一定要使用object类型:

    In [433]: df.select_dtypes(include=['object'])
    Out[433]: 
      string
    0      a
    1      b
    2      c
    

    如果要得到像numpy.number这样的泛型类型的子类型,你可以自定义一个函数来返回子类型树。

    In [434]: def subdtypes(dtype):
       .....:     subs = dtype.__subclasses__()
       .....:     if not subs:
       .....:         return dtype
       .....:     return [dtype, [subdtypes(dt) for dt in subs]]
       .....: 
    

    所有的NumPy数据类型都是numpy.generic的子类:

    In [435]: subdtypes(np.generic)
    Out[435]: 
    [numpy.generic,
     [[numpy.number,
       [[numpy.integer,
         [[numpy.signedinteger,
           [numpy.int8,
            numpy.int16,
            numpy.int32,
            numpy.int64,
            numpy.int64,
            numpy.timedelta64]],
          [numpy.unsignedinteger,
           [numpy.uint8,
            numpy.uint16,
            numpy.uint32,
            numpy.uint64,
            numpy.uint64]]]],
        [numpy.inexact,
         [[numpy.floating,
           [numpy.float16, numpy.float32, numpy.float64, numpy.float128]],
          [numpy.complexfloating,
           [numpy.complex64, numpy.complex128, numpy.complex256]]]]]],
      [numpy.flexible,
       [[numpy.character, [numpy.bytes_, numpy.str_]],
        [numpy.void, [numpy.record]]]],
      numpy.bool_,
      numpy.datetime64,
      numpy.object_]]
    

    注意: pandas也自定义了category和datetime64[ns,tz]类型,这些类型并没有集成在NumPy数据类型层级内,因此也不会再上面的函数返回的结果中出现。

    相关文章

      网友评论

        本文标题:pandas0.24.1文档3.3 基础功能(三)

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