《Python数据分析基础教程:NumPy学习指南(第2版)》笔记15:第七章 专用函数1——排序

本文介绍了NumPy中的排序和搜索函数,包括sort、lexsort、argsort等排序函数及argmax、argmin、searchsorted等搜索函数。通过实例展示了如何使用lexsort按字典序排序数据,以及使用searchsorted函数在有序数组中查找合适的位置。

第七章 专用函数

本章主要介绍金融计算或信号处理方面的Numpy函数。

7.1 排序

NumPy提供了多种排序函数,如下所示:

  • sort函数返回排序后的数组;
  • lexsort函数根据键值的字典序进行排序;
  • argsort函数返回输入数组排序后的下标;
  • ndarray类的sort方法可对数组进行原位排序;
  • msort函数沿着第一个轴排序;
  • sort_complex函数对复数按照先实部后虚部的顺序进行排序。
    在上面的列表中, argsortsort函数可用来对NumPy数组类型进行排序。

7.2 动手实践:按字典序排序

NumPy中的lexsort函数返回输入数组按字典序排序后的下标。我们需要给lexsort函数提供排序所依据的键值数组或元组。步骤如下。

  • (1) 回顾一下第3章中我们使用的AAPL股价数据,现在我们要将这些很久以前的数据用在完全不同的地方。我们将载入收盘价和日期数据。是的,处理日期总是很复杂,我们为其准备了专门的转换函数。

    import numpy as np
    import datetime
    
    def datestr2num(s):
        return datetime.datetime.strptime(s.decode('ascii'), "%d-%m-%Y").toordinal()
    
    dates,closes=np.loadtxt('AAPL.csv', delimiter=',', usecols=(1, 6), converters={1:datestr2num}, unpack=True)
    
  • (2) 使用lexsort函数排序。数据本身已经按照日期排序,不过我们现在优先按照收盘价排序

    indices = np.lexsort((dates, closes))
    
    print( "Indices", indices)
    print( ["%s %s" % (datetime.date.fromordinal(int(dates[i])),  closes[i]) for i in indices])
    

    输出结果如下:

    Indices [ 0 16  1 17 18  4  3  2  5 28 19 21 15  6 29 22 27 20  9  7 25 26 10  8
     14 11 23 12 24 13]
    ['2011-01-28 336.1', '2011-02-22 338.61', '2011-01-31 339.32', '2011-02-23 342.62', '2011-02-24 342.88', '2011-02-03 343.44', '2011-02-02 344.32', '2011-02-01 345.03', '2011-02-04 346.5', '2011-03-10 346.67', '2011-02-25 348.16', '2011-03-01 349.31', '2011-02-18 350.56', '2011-02-07 351.88', '2011-03-11 351.99', '2011-03-02 352.12', '2011-03-09 352.47', '2011-02-28 353.21', '2011-02-10 354.54', '2011-02-08 355.2', '2011-03-07 355.36', '2011-03-08 355.76', '2011-02-11 356.85', '2011-02-09 358.16', '2011-02-17 358.3', '2011-02-14 359.18', '2011-03-03 359.56', '2011-02-15 359.9', '2011-03-04 360.0', '2011-02-16 363.13']
    

案例完整代码如下:

import numpy as np
import datetime

def datestr2num(s):
    return datetime.datetime.strptime(s.decode('ascii'), "%d-%m-%Y").toordinal()

dates,closes=np.loadtxt('AAPL.csv', delimiter=',', usecols=(1, 6), converters={1:datestr2num}, unpack=True)
indices = np.lexsort((dates, closes))

print( "Indices", indices)
print( ["%s %s" % (datetime.date.fromordinal(int(dates[i])),  closes[i]) for i in indices])

7.3 复数

复数包含实数部分和虚数部分。如同在前面的章节中提到的, NumPy中有专门的复数类型,使用两个浮点数来表示复数。这些复数可以使用NumPysort_complex函数进行排序。该函数按照先实部后虚部的顺序排序。

7.4 动手实践:对复数进行排序

我们将创建一个复数数组并进行排序,步骤如下。

  • (1) 生成5个随机数作为实部, 5个随机数作为虚部。设置随机数种子为42

    import numpy as np
    
    np.random.seed(42)
    complex_numbers = np.random.random(5) + 1j * np.random.random(5)
    print("Complex numbers\n", complex_numbers)
    

    输出为:

    Complex numbers
     [0.37454012+0.15599452j 0.95071431+0.05808361j 0.73199394+0.86617615j
     0.59865848+0.60111501j 0.15601864+0.70807258j]
    
  • (2) 调用sort_complex函数对上面生成的复数进行排序:

    print("Sorted\n", np.sort_complex(complex_numbers))
    

    排序后的结果如下:

    Sorted
     [0.15601864+0.70807258j 0.37454012+0.15599452j 0.59865848+0.60111501j
     0.73199394+0.86617615j 0.95071431+0.05808361j]
    

案例完整代码如下:

import numpy as np

np.random.seed(42)
complex_numbers = np.random.random(5) + 1j * np.random.random(5)
print("Complex numbers\n", complex_numbers)
print("Sorted\n", np.sort_complex(complex_numbers))

7.5 搜索

NumPy中有多个函数可以在数组中进行搜索,如下所示。

  • argmax函数返回数组中最大值对应的下标。

    >>> a = np.array([2, 4, 8])
    >>> np.argmax(a)
    2
    
  • nanargmax函数提供相同的功能,但忽略NaN值。

    >>> b = np.array([np.nan, 2, 4])
    >>> np.nanargmax(b)
    2
    
  • argminnanargmin函数的功能类似,只不过换成了最小值。

  • argwhere函数根据条件搜索非零的元素,并分组返回对应的下标。

    >>> a = np.array([2, 4, 8])
    >>> np.argwhere(a <= 4)
    array([[0],
    [1]])
    
  • searchsorted函数可以为指定的插入值寻找维持数组排序的索引位置。该函数使用二分搜索算法,计算复杂度为O(log(n))

  • extract函数返回满足指定条件的数组元素。

7.6 动手实践:使用searchsorted函数

searchsorted函数为指定的插入值返回一个在有序数组中的索引位置,从这个位置插入可以保持数组的有序性。下面的例子可以解释得更清楚。请完成如下步骤。

  • (1) 我们需要一个排序后的数组。使用arange函数创建一个升序排列的数组:

    import numpy as np
    
    a = np.arange(5)
    
  • (2) 现在,我们来调用searchsorted函数:

    indices = np.searchsorted(a, [-2, 7])
    print("Indices", indices)
    

    下面的索引即可以维持数组排序的插入位置:

    Indices [0 5]
    
  • (3) 使用insert函数构建完整的数组:

    print("The full array", np.insert(a, indices, [-2, 7]))
    

    结果如下:

    The full array [-2 0 1 2 3 4 7]
    

案例完整代码如下:

import numpy as np

a = np.arange(5)
indices = np.searchsorted(a, [-2, 7])
print("Indices", indices)

print("The full array", np.insert(a, indices, [-2, 7]))

7.7 数组元素抽取

NumPy的**extract函数可以根据某个条件从数组中抽取元素**。该函数和我们在第3章中遇到过的where函数相似。 nonzero函数专门用来抽取非零的数组元素

7.8 动手实践:从数组中抽取元素

我们要从一个数组中抽取偶数元素,步骤如下。

  • (1) 使用arange函数创建数组:

    import numpy as np
    
    a = np.arange(7)
    
  • (2) 生成选择偶数元素的条件变量:

    condition = (a % 2) == 0
    
  • (3) 使用extract函数基于生成的条件从数组中抽取元素:

    print("Even numbers", np.extract(condition, a))
    

    输出数组中的偶数元素,如下所示:

    Even numbers [0 2 4 6]
    
  • (4) 使用nonzero函数抽取数组中的非零元素:

    print("Non zero", np.nonzero(a))
    

    输出结果如下:

    Non zero (array([1, 2, 3, 4, 5, 6]),)
    

案例完整代码如下:

import numpy as np

a = np.arange(7)
condition = (a % 2) == 0
print("Even numbers", np.extract(condition, a))
print("Non zero", np.nonzero(a))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值