小秩学数据分析数据蛙数据分析每周作业

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

2019-04-09  本文已影响6人  Lykit01

目录:
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的值:

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类型数组转换为指定的类型:

In [374]: m = ['1.1', 2, 3]

In [375]: pd.to_numeric(m)
Out[375]: array([ 1.1,  2. ,  3. ])
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)
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数据类型层级内,因此也不会再上面的函数返回的结果中出现。

上一篇下一篇

猜你喜欢

热点阅读