Pandas 中文官档~基础用法5

作者: 呆鸟的简书 | 来源:发表于2019-10-28 10:38 被阅读0次

    .dt 访问器

    Series 提供了一个可以简单、快捷返回 datetime 属性值的访问器。这个访问器返回的也是 Series,索引与现有的 Series 一样。

    # datetime
    In [264]: s = pd.Series(pd.date_range('20130101 09:10:12', periods=4))
    
    In [265]: s
    Out[265]: 
    0   2013-01-01 09:10:12
    1   2013-01-02 09:10:12
    2   2013-01-03 09:10:12
    3   2013-01-04 09:10:12
    dtype: datetime64[ns]
    
    In [266]: s.dt.hour
    Out[266]: 
    0    9
    1    9
    2    9
    3    9
    dtype: int64
    
    In [267]: s.dt.second
    Out[267]: 
    0    12
    1    12
    2    12
    3    12
    dtype: int64
    
    In [268]: s.dt.day
    Out[268]: 
    0    1
    1    2
    2    3
    3    4
    dtype: int64
    

    用下列表达式进行筛选非常方便:

    In [269]: s[s.dt.day == 2]
    Out[269]: 
    1   2013-01-02 09:10:12
    dtype: datetime64[ns]
    

    还可以轻易实现时区转换:

    In [270]: stz = s.dt.tz_localize('US/Eastern')
    
    In [271]: stz
    Out[271]: 
    0   2013-01-01 09:10:12-05:00
    1   2013-01-02 09:10:12-05:00
    2   2013-01-03 09:10:12-05:00
    3   2013-01-04 09:10:12-05:00
    dtype: datetime64[ns, US/Eastern]
    
    In [272]: stz.dt.tz
    Out[272]: <DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>
    

    还可以把这些操作连在一起:

    In [273]: s.dt.tz_localize('UTC').dt.tz_convert('US/Eastern')
    Out[273]: 
    0   2013-01-01 04:10:12-05:00
    1   2013-01-02 04:10:12-05:00
    2   2013-01-03 04:10:12-05:00
    3   2013-01-04 04:10:12-05:00
    dtype: datetime64[ns, US/Eastern]
    

    还可以用 Series.dt.strftime()datetime 的值当成字符串进行格式化,支持与标准的 strftime() 同样的格式。

    # DatetimeIndex
    In [274]: s = pd.Series(pd.date_range('20130101', periods=4))
    
    In [275]: s
    Out[275]: 
    0   2013-01-01
    1   2013-01-02
    2   2013-01-03
    3   2013-01-04
    dtype: datetime64[ns]
    
    In [276]: s.dt.strftime('%Y/%m/%d')
    Out[276]: 
    0    2013/01/01
    1    2013/01/02
    2    2013/01/03
    3    2013/01/04
    dtype: object
    
    # PeriodIndex
    In [277]: s = pd.Series(pd.period_range('20130101', periods=4))
    
    In [278]: s
    Out[278]: 
    0    2013-01-01
    1    2013-01-02
    2    2013-01-03
    3    2013-01-04
    dtype: period[D]
    
    In [279]: s.dt.strftime('%Y/%m/%d')
    Out[279]: 
    0    2013/01/01
    1    2013/01/02
    2    2013/01/03
    3    2013/01/04
    dtype: object
    

    .dt 访问器还支持 periodtimedelta

    # period
    In [280]: s = pd.Series(pd.period_range('20130101', periods=4, freq='D'))
    
    In [281]: s
    Out[281]: 
    0    2013-01-01
    1    2013-01-02
    2    2013-01-03
    3    2013-01-04
    dtype: period[D]
    
    In [282]: s.dt.year
    Out[282]: 
    0    2013
    1    2013
    2    2013
    3    2013
    dtype: int64
    
    In [283]: s.dt.day
    Out[283]: 
    0    1
    1    2
    2    3
    3    4
    dtype: int64
    
    # timedelta
    In [284]: s = pd.Series(pd.timedelta_range('1 day 00:00:05', periods=4, freq='s'))
    
    In [285]: s
    Out[285]: 
    0   1 days 00:00:05
    1   1 days 00:00:06
    2   1 days 00:00:07
    3   1 days 00:00:08
    dtype: timedelta64[ns]
    
    In [286]: s.dt.days
    Out[286]: 
    0    1
    1    1
    2    1
    3    1
    dtype: int64
    
    In [287]: s.dt.seconds
    Out[287]: 
    0    5
    1    6
    2    7
    3    8
    dtype: int64
    
    In [288]: s.dt.components
    Out[288]: 
       days  hours  minutes  seconds  milliseconds  microseconds  nanoseconds
    0     1      0        0        5             0             0            0
    1     1      0        0        6             0             0            0
    2     1      0        0        7             0             0            0
    3     1      0        0        8             0             0            0
    

    ::: tip 注意

    用这个访问器处理不是 datetime 类型的值时,Series.dt 会触发 TypeError 错误。

    :::

    矢量化字符串方法

    Series 支持字符串处理方法,操作数组中每个元素十分方便。这些方法会自动排除缺失值与空值,这也许是其最重要的特性。这些方法通过 Series 的 str 属性访问,一般情况下,这些操作的名称与内置的字符串方法一致。示例如下:

    In [289]: s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])
    
    In [290]: s.str.lower()
    Out[290]: 
    0       a
    1       b
    2       c
    3    aaba
    4    baca
    5     NaN
    6    caba
    7     dog
    8     cat
    dtype: object
    

    这里还提供了强大的模式匹配方法,但工业注意,模式匹配方法默认使用正则表达式

    参阅矢量化字符串方法了解完整内容。

    排序

    Pandas 支持三种排序方式,按索引标签排序,按列里的值排序,按两种方式混合排序。

    按索引排序

    Series.sort_index()DataFrame.sort_index() 方法用于按索引层级对 pandas 对象排序。

    In [291]: 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 [292]: unsorted_df = df.reindex(index=['a', 'd', 'c', 'b'],
       .....:                          columns=['three', 'two', 'one'])
       .....: 
    
    In [293]: unsorted_df
    Out[293]: 
          three       two       one
    a       NaN -1.152244  0.562973
    d -0.252916 -0.109597       NaN
    c  1.273388 -0.167123  0.640382
    b -0.098217  0.009797 -1.299504
    
    # DataFrame
    In [294]: unsorted_df.sort_index()
    Out[294]: 
          three       two       one
    a       NaN -1.152244  0.562973
    b -0.098217  0.009797 -1.299504
    c  1.273388 -0.167123  0.640382
    d -0.252916 -0.109597       NaN
    
    In [295]: unsorted_df.sort_index(ascending=False)
    Out[295]: 
          three       two       one
    d -0.252916 -0.109597       NaN
    c  1.273388 -0.167123  0.640382
    b -0.098217  0.009797 -1.299504
    a       NaN -1.152244  0.562973
    
    In [296]: unsorted_df.sort_index(axis=1)
    Out[296]: 
            one     three       two
    a  0.562973       NaN -1.152244
    d       NaN -0.252916 -0.109597
    c  0.640382  1.273388 -0.167123
    b -1.299504 -0.098217  0.009797
    
    # Series
    In [297]: unsorted_df['three'].sort_index()
    Out[297]: 
    a         NaN
    b   -0.098217
    c    1.273388
    d   -0.252916
    Name: three, dtype: float64
    

    按值排序

    Series.sort_values() 方法用于按值对 Series 排序。DataFrame.sort_values() 方法用于按行列的值对 DataFrame 排序。DataFrame.sort_values() 的可选参数 by 用于指定按哪列排序,该参数的值可以是一列或多列数据。

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

    参数 by 支持列名列表,示例如下:

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

    这些方法支持用 na_position 参数处理空值。

    In [301]: s[2] = np.nan
    
    In [302]: s.sort_values()
    Out[302]: 
    0       A
    3    Aaba
    1       B
    4    Baca
    6    CABA
    8     cat
    7     dog
    2     NaN
    5     NaN
    dtype: object
    
    In [303]: s.sort_values(na_position='first')
    Out[303]: 
    2     NaN
    5     NaN
    0       A
    3    Aaba
    1       B
    4    Baca
    6    CABA
    8     cat
    7     dog
    dtype: object
    

    按索引与值排序

    0.23.0 版新增

    通过参数 by 传递给 DataFrame.sort_values() 的字符串可以引用列或索引层名。

    # 创建 MultiIndex
    In [304]: idx = pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('a', 2),
       .....:                                 ('b', 2), ('b', 1), ('b', 1)])
       .....: 
    
    In [305]: idx.names = ['first', 'second']
    
    # 创建 DataFrame
    In [306]: df_multi = pd.DataFrame({'A': np.arange(6, 0, -1)},
       .....:                         index=idx)
       .....: 
    
    In [307]: df_multi
    Out[307]: 
                  A
    first second   
    a     1       6
          2       5
          2       4
    b     2       3
          1       2
          1       1
    

    second(索引)与 A(列)排序。

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

    ::: tip 注意

    如果字符串、列名、索引层名重名,会触发警告提示,并以列名为准。后期版本中,这种情况将会触发模糊错误。

    :::

    搜索排序

    Series 支持 searchsorted() 方法,这与numpy.ndarray.searchsorted() 的操作方式类似。

    In [309]: ser = pd.Series([1, 2, 3])
    
    In [310]: ser.searchsorted([0, 3])
    Out[310]: array([0, 2])
    
    In [311]: ser.searchsorted([0, 4])
    Out[311]: array([0, 3])
    
    In [312]: ser.searchsorted([1, 3], side='right')
    Out[312]: array([1, 3])
    
    In [313]: ser.searchsorted([1, 3], side='left')
    Out[313]: array([0, 2])
    
    In [314]: ser = pd.Series([3, 1, 2])
    
    In [315]: ser.searchsorted([0, 3], sorter=np.argsort(ser))
    Out[315]: array([0, 2])
    

    最大值与最小值

    Series 支持 nsmallest()nlargest() 方法,本方法返回 N 个最大或最小的值。对于数据量大的 Series 来说,该方法比先为整个 Series 排序,再调用 head(n) 这种方式的速度要快得多。

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

    DataFrame 也支持 nlargestnsmallest 方法。

    In [321]: 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 [322]: df.nlargest(3, 'a')
    Out[322]: 
        a  b    c
    5  11  f  3.0
    3  10  c  3.2
    4   8  e  NaN
    
    In [323]: df.nlargest(5, ['a', 'c'])
    Out[323]: 
        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 [324]: df.nsmallest(3, 'a')
    Out[324]: 
       a  b    c
    0 -2  a  1.0
    1 -1  b  2.0
    6 -1  f  4.0
    
    In [325]: df.nsmallest(5, ['a', 'c'])
    Out[325]: 
       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
    

    用多重索引的列排序

    列为多重索引时,还可以显式排序,用 by 可以指定所有层级。

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

    复制

    在 pandas 对象上执行 copy() 方法,将复制底层数据(但不包括轴索引,因为轴索引不可变),并返回一个新的对象。注意,复制对象这种操作一般来说不是必须的。比如说,以下几种方式可以就地(inplace) 改变 DataFrame:

    • 插入、删除、修改列
    • indexcolumns 属性赋值
    • 对于同质数据,用 values 属性或高级索引即可直接修改值

    注意,用 pandas 方法修改数据不会带来任何副作用,几乎所有方法都返回新的对象,不会修改原始数据对象。如果原始数据有所改动,唯一的可能就是用户显式指定了要修改原始数据。

    相关文章

      网友评论

        本文标题:Pandas 中文官档~基础用法5

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