Numpy通用函数及向量化计算

Python(Cpython)对于较大数组的循环操作会比较慢,因为Python的动态性和解释性,在做每次循环时,必须做数据类型的检查和函数的调度。

Numpy为很多类型的操作提供了非常方便的、静态类型的、可编译程序的接口,称为向量操作,通过通用函数实现,使数组中的数据运算执行效率更快。

In [3]: import numpy as np

In [4]: arr = np.arange(10)
In [5]: arr
Out[5]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

#arr数组中的每个元素都执行一次sqrt函数(开方)
In [6]: np.sqrt(arr)
Out[6]:
array([0.        , 1.        , 1.41421356, 1.73205081, 2.        ,
       2.23606798, 2.44948974, 2.64575131, 2.82842712, 3.        ])

#arr数组中的每个元素都执行一次exp函数(指数)
In [7]: np.exp(arr)
Out[7]:
array([1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01,
       5.45981500e+01, 1.48413159e+02, 4.03428793e+02, 1.09663316e+03,
       2.98095799e+03, 8.10308393e+03])

In [8]: x = np.random.randn(10)
In [9]: y = np.random.randn(10)

In [10]: x
Out[10]:
array([-0.82366085, -0.03255978,  2.50626464,  0.33865153,  0.43386721,
       -0.74543163, -2.64879417, -1.07827856, -0.29578612,  1.47010253])

In [11]: y
Out[11]:
array([-0.29522902,  0.37414633, -1.05189119, -1.17025433,  1.03573013,
       -0.20660426,  1.06281893, -0.49384468, -1.8739977 ,  1.25588708])

#maximum对x和y数组相应位置的元素逐个比较,并输出值较大的
In [12]: np.maximum(x,y)
Out[12]:
array([-0.29522902,  0.37414633,  2.50626464,  0.33865153,  1.03573013,
       -0.20660426,  1.06281893, -0.49384468, -0.29578612,  1.47010253])


In [13]: arr = np.random.randn(7)*5

In [14]: arr
Out[14]:
array([  4.98279157,  -1.27419373,   4.16720012, -10.48931255,
         4.49418926,   0.735708  ,   0.07716139])

#modf函数分别获取数组中每个元素的整数和小数
In [15]: reminder,whole_part = np.modf(arr)
    
In [16]: reminder
Out[16]:
array([ 0.98279157, -0.27419373,  0.16720012, -0.48931255,  0.49418926,
        0.735708  ,  0.07716139])

In [17]: whole_part
Out[17]: array([  4.,  -1.,   4., -10.,   4.,   0.,   0.])

In [18]: arr
Out[18]:
array([  4.98279157,  -1.27419373,   4.16720012, -10.48931255,
         4.49418926,   0.735708  ,   0.07716139])

In [19]: np.sqrt(arr)
Out[19]:
array([2.23221674,        nan, 2.04137212,        nan, 2.1199503 ,
       0.85773423, 0.27777938])

In [20]: arr
Out[20]:
array([  4.98279157,  -1.27419373,   4.16720012, -10.48931255,
         4.49418926,   0.735708  ,   0.07716139])

#sqrt(x, /[, out, where, casting, order, …]),x表示输入的数组,out表示存放的位置
#np.sqrt(arr,arr)表示对arr数组开方,并把结果存入原来arr数组中,则原来arr数组中的数就会发生变化
In [21]: np.sqrt(arr,arr)
Out[21]:
array([2.23221674,        nan, 2.04137212,        nan, 2.1199503 ,
       0.85773423, 0.27777938])

In [22]: arr
Out[22]:
array([2.23221674,        nan, 2.04137212,        nan, 2.1199503 ,
       0.85773423, 0.27777938])

向量化计算

数组的向量化计算可以同时处理数组需要循环才能完成的任务,效率比循环更高。

In [23]: points = np.arange(-5,5,0.01)

#meshgrid创建一个规则的数值网格,xs为x轴网格线,ys为y轴网格线 
In [24]: xs, ys = np.meshgrid(points,points)

In [25]: xs
Out[25]:
array([[-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       ...,
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99]])

In [26]: ys
Out[26]:
array([[-5.  , -5.  , -5.  , ..., -5.  , -5.  , -5.  ],
       [-4.99, -4.99, -4.99, ..., -4.99, -4.99, -4.99],
       [-4.98, -4.98, -4.98, ..., -4.98, -4.98, -4.98],
       ...,
       [ 4.97,  4.97,  4.97, ...,  4.97,  4.97,  4.97],
       [ 4.98,  4.98,  4.98, ...,  4.98,  4.98,  4.98],
       [ 4.99,  4.99,  4.99, ...,  4.99,  4.99,  4.99]])

In [27]: z = np.sqrt(xs ** 2 + ys ** 2)

In [28]: z
Out[28]:
array([[7.07106781, 7.06400028, 7.05693985, ..., 7.04988652, 7.05693985,
        7.06400028],
       [7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,
        7.05692568],
       [7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,
        7.04985815],
       ...,
       [7.04988652, 7.04279774, 7.03571603, ..., 7.0286414 , 7.03571603,
        7.04279774],
       [7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,
        7.04985815],
       [7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,
        7.05692568]])

In [29]: import matplotlib.pyplot as plt
#imshow画图形
In [30]: plt.imshow(z,cmap=plt.cm.gray);plt.colorbar()
Out[30]: <matplotlib.colorbar.Colorbar at 0x20351df58c8>
#title画图形标题
In [31]: plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
Out[31]: Text(0.5, 1, 'Image plot of $\\sqrt{x^2 + y^2}$ for a grid of values')

数组条件逻辑运算

numpy.where(condition,x,y)是一个向量化的三元表达式(x if condition==True else y)。

In [32]: xarr = np.array([1.1,1.2,1.3,1.4,1.5])
In [33]: yarr = np.array([2.1,2.2,2.3,2.4,2.5])
In [34]: cond = np.array([True, False, True, True, False])

#通过列表表达式+for\zip实现  
In [35]: result = [(x if c else y) for x,y,c in zip(xarr, yarr, cond)]
In [36]: result
Out[36]: [1.1, 2.2, 1.3, 1.4, 2.5]

#np.where()直接实现上面列表表达式的逻辑
In [38]: result = np.where(cond,xarr,yarr)
In [39]: result
Out[39]: array([1.1, 2.2, 1.3, 1.4, 2.5])

In [40]: arr = np.random.randn(4,4)
In [41]: arr
Out[41]:
array([[ 1.59209108, -0.4086942 ,  0.4407095 ,  1.15434273],
       [-0.4809145 , -1.22923284, -1.15852576,  1.29476618],
       [ 0.15114022, -0.78129023, -0.51957822, -0.39520662],
       [ 0.13733152,  1.55691611, -2.31871851, -0.26706437]])

In [42]: arr > 0
Out[42]:
array([[ True, False,  True,  True],
       [False, False, False,  True],
       [ True, False, False, False],
       [ True,  True, False, False]])

In [43]: np.where(arr >0 ,1,0)
Out[43]:
array([[1, 0, 1, 1],
       [0, 0, 0, 1],
       [1, 0, 0, 0],
       [1, 1, 0, 0]])

In [44]: np.where(arr >0,1,arr)
Out[44]:
array([[ 1.        , -0.4086942 ,  1.        ,  1.        ],
       [-0.4809145 , -1.22923284, -1.15852576,  1.        ],
       [ 1.        , -0.78129023, -0.51957822, -0.39520662],
       [ 1.        ,  1.        , -2.31871851, -0.26706437]])

数学和统计方法

In [45]: arr = np.random.randn(5,4)
In [46]: arr
Out[46]:
array([[ 0.46511456, -0.75494472, -0.11214598,  0.89848079],
       [-1.42332991,  0.337035  , -0.22018627, -0.33635835],
       [-2.9157174 , -2.04946947, -1.46504217, -2.1854843 ],
       [ 0.91287505,  0.20984805,  0.58966139,  1.18746111],
       [-0.08732871, -1.36381031, -0.10451817, -0.90514938]])

#mean()求平均值,默认求全部元素的平均值,加入参数axis=0表示沿0轴求平均值,axis=1表示沿1轴求平均值
In [47]: arr.mean()
Out[47]: -0.46615045863486665

In [48]: np.mean(arr)
Out[48]: -0.46615045863486665

In [49]: arr.mean(axis=1)
Out[49]: array([ 0.12412616, -0.41070988, -2.15392833,  0.7249614 , -0.61520164])

In [50]: arr.mean(axis=0)
Out[50]: array([-0.60967728, -0.72426829, -0.26244624, -0.26821002])

#sum()求和,默认求全部元素的和,加入参数axis=0表示沿0轴求和,axis=1表示沿1轴求和
In [51]: arr.sum()
Out[51]: -9.323009172697333

In [52]: arr.sum(axis=1)
Out[52]: array([ 0.49650465, -1.64283952, -8.61571333,  2.89984559, -2.46080656])

In [53]: arr.sum(axis=0)
Out[53]: array([-3.04838641, -3.62134144, -1.31223119, -1.34105012])
   
In [54]: arr = np.array([[0,1,2],[3,4,5],[6,7,8]])
In [55]: arr
Out[55]:
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
#cumsum()求累计和,默认求全部元素的累计和,加入参数axis=0表示沿0轴求累计和,axis=1表示沿1轴求累计和
In [56]: arr.cumsum(axis=0)
Out[56]:
array([[ 0,  1,  2],
       [ 3,  5,  7],
       [ 9, 12, 15]], dtype=int32)

In [57]: arr.cumsum(axis=1)
Out[57]:
array([[ 0,  1,  3],
       [ 3,  7, 12],
       [ 6, 13, 21]], dtype=int32)
#cumprod()求累积,默认求全部元素的累积,加入参数axis=0表示沿0轴求累积,axis=1表示沿1轴求累积
In [58]: arr.cumprod(axis=0)
Out[58]:
array([[ 0,  1,  2],
       [ 0,  4, 10],
       [ 0, 28, 80]], dtype=int32)

In [59]: arr.cumprod(axis=1)
Out[59]:
array([[  0,   0,   0],
       [  3,  12,  60],
       [  6,  42, 336]], dtype=int32)

布尔运算方法

In [60]: arr = np.random.randn(100)
In [61]: arr
Out[61]:
array([ 1.97279219,  1.56694167, -0.55398407,  0.15938761, -1.90688396,
        0.12198921,  0.36810009,  0.23750045, -0.45220466,  0.02077729,
       -0.65948605,  0.57359337, -0.66764519, -0.14284721,  0.19014932,
        0.91210127, -1.23914144,  0.53690069, -0.522095  , -0.99396945,
       -0.25311752,  0.89034877, -0.8311114 , -0.16252583, -0.27005923,
       -0.55920499,  1.73472904, -0.01973033,  0.92402808, -0.16614446,
        0.2736938 , -0.28145616, -0.09546974,  0.530437  ,  0.39995646,
       -0.85350062, -0.51831624, -1.69345104, -0.64163665, -0.39480043,
        1.38246309,  1.06339284,  1.18405756,  2.03400374, -0.42610591,
        0.35906461, -0.55486399,  0.70110865, -0.78864601, -0.29954069,
        1.94746481, -0.52377169,  0.24632122,  0.62128442, -0.5238096 ,
        0.56636735, -0.00591474,  1.66648525,  1.5606595 , -0.86025501,
        1.13356963, -1.55629377, -0.91746296, -0.69410977,  1.96398699,
        0.15773424,  0.1475058 , -0.48767326,  0.65743225, -2.43297787,
       -0.14665574, -1.16361457, -0.9753315 , -0.17658007,  0.07366705,
       -0.34816566, -0.19779013, -0.26078629,  0.64939326,  0.68780731,
        0.2898325 , -0.29745762,  1.35564769, -1.71548972, -1.309609  ,
        0.33786133, -0.00713603, -2.01114545, -0.41214938,  0.20788337,
       -0.70684644, -3.2529954 ,  0.69005349,  1.5902472 , -0.54671729,
        1.58654547,  0.03035015,  0.62181632,  0.14706786, -0.90948163])
#用arr > 0的条件判断,满足的元素相加
In [62]: (arr > 0 ).sum()
Out[62]: 47

In [63]: bools = np.array([False,False,True,False])
#any()数组中有一个True,则返回True
In [65]: bools.any()
Out[65]: True
#all()数组中所有的元素为True才返回True
In [66]: bools.all()
Out[66]: False

数组排列

sort()排列后直接替换原来的数组。

In [67]: arr = np.random.randn(6)

In [68]: arr
Out[68]:
array([-0.8710231 ,  0.48971206, -0.65277359, -0.09909771,  0.45533796,
       -0.02159873])
#sort()元素排列后直接替换原来的数组
In [69]: arr.sort()
In [70]: arr
Out[70]:
array([-0.8710231 , -0.65277359, -0.09909771, -0.02159873,  0.45533796,
        0.48971206])


In [71]: arr = np.random.randn(5,3)
In [72]: arr
Out[72]:
array([[-0.10113188, -0.21734814, -0.76523088],
       [-0.46665726, -0.25147201, -1.09096503],
       [ 0.71719542,  0.21011708,  0.09206453],
       [-0.22847625,  0.26928708, -0.3253391 ],
       [ 1.3526748 , -1.61463912, -0.19217378]])
#沿1轴排序
In [73]: arr.sort(1)

In [74]: arr
Out[74]:
array([[-0.76523088, -0.21734814, -0.10113188],
       [-1.09096503, -0.46665726, -0.25147201],
       [ 0.09206453,  0.21011708,  0.71719542],
       [-0.3253391 , -0.22847625,  0.26928708],
       [-1.61463912, -0.19217378,  1.3526748 ]])

唯一性计算

np.unique()返回唯一并且排好序的数组。

In [75]: names = np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
#提取names数组中的唯一元素,并排好序返回
In [76]: np.unique(names)
Out[76]: array(['Bob', 'Joe', 'Will'], dtype='<U4')

In [77]: ints = np.array([3,3,3,2,2,1,1,4,4])

In [78]: np.unique(ints)
Out[78]: array([1, 2, 3, 4])

In [79]: values = np.array([6,0,0,3,2,5,6])
#np.in1d(x,y)判断x中的元素是否包含在y中,是返回True,否返回False
In [80]: np.in1d(values,[2,3,6])
Out[80]: array([ True, False, False,  True,  True, False,  True])
posted @ 2021-12-17 16:45  溪奇的数据  阅读(181)  评论(0编辑  收藏  举报