Python数据分析系列2---通用函数和利用数组进行数据处理

一、通用函数:快速的元素级数组函数

通用函数(即ufunc)是一种对ndarray中的数据执行元素级运算的函数。(将只对一个元素的操作直接用在多维数组对象身上)

一元通用函数:许多ufunc都是简单的元素级变体,如sqrt和exp:

```python
In [137]: arr = np.arange(10)

In [138]: arr
Out[138]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [139]: np.sqrt(arr)
Out[139]: 
array([ 0.    ,  1.    ,  1.4142,  1.7321,  2.    ,  2.2361,  2.4495,
        2.6458,  2.8284,  3.    ])

In [140]: np.exp(arr)
Out[140]: 
array([    1.    ,     2.7183,     7.3891,    20.0855,    54.5982,
         148.4132,   403.4288,  1096.6332,  2980.958 ,  8103.0839])
```

二元通用函数:另外一些通用函数(例如maximum)会接受2个数组(因此也叫二元(binary)ufunc),并返回一个结果数组:

```python
In [141]: x = np.random.randn(8)

In [142]: y = np.random.randn(8)

In [143]: x
Out[143]: 
array([-0.0119,  1.0048,  1.3272, -0.9193, -1.5491,  0.0222,  0.7584,
       -0.6605])

In [144]: y
Out[144]: 
array([ 0.8626, -0.01  ,  0.05  ,  0.6702,  0.853 , -0.9559, -0.0235,
       -2.3042])

In [145]: np.maximum(x, y)
Out[145]: 
array([ 0.8626,  1.0048,  1.3272,  0.6702,  0.853 ,  0.0222,  0.7584,   
       -0.6605])
```

ufunc函数的广播机制 

广播(broadcasting)是指不同形状的数组之间执行算术运算的方式。广播机制需要遵循4个原则:

①所有输入的数组都向其中shape最长的数组看齐,shape中不足的部分通过在前面加1补齐;

②输出数组的shape是输入数组shape各个轴上的最大值;

③如果输入数组的某个轴 和 输出数组的对应轴 的长度相同或者其长度为1时,这个数组可以用来计算,否则会出错。

④当输入数组的某个轴的长度为1时,沿着此轴运算都用此轴上的第一组值

In[32]:
arr1 = np.array([[0,0,0],[1,1,1],[2,2,2]])
arr2 = np.array([1,2,3])
print('arr1:\n,arr1')
print('arr2:\n,arr2')
print('arr1+arr2:\n,arr1+arr2')

Out[32]:
arr1:
 [[0 0 0]
 [1 1 1]
 [2 2 2]]
arr2:
 [1 2 3]
arr1+arr2:
 [[1 2 3]
 [2 3 4]
 [3 4 5]]

二、矢量化

Numpy数组可以将许多数据处理任务用简洁的数组表达式表示(避免循环)。

这种用数组表达式代替循环的做法,通常被叫做矢量化。矢量化数组运算比原始的Python速度快上一两个数量级,尤其在各种数值计算中。后面将介绍广播:一种针对矢量化的强大手段。

三、条件逻辑运算

条件循环:numpy.where函数是三元表达式x if condition else y的矢量化版本。

使用原始Python方法:

```python
In [165]: xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
In [166]: yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
In [167]: cond = np.array([True, False, True, True, False])
```python
In [168]: result = [(x if c else y)
   .....:           for x, y, c in zip(xarr, yarr, cond)]
In [169]: result
Out[169]: [1.1000000000000001, 2.2000000000000002, 1.3, 1.3999999999999999, 2.5]
```

使用np.where,则可以将该功能写得非常简洁:

```python
In [170]: result = np.where(cond, xarr, yarr)

In [171]: result
Out[171]: array([ 1.1,  2.2,  1.3,  1.4,  2.5])
```

np.where的第二个和第三个参数不必是数组,它们都可以是标量值。在数据分析工作中,where通常用于根据另一个数组而产生一个新的数组。

例如,假设有一个由随机数据组成的矩阵,你希望将所有正值替换为2,将所有负值替换为-2。若利用np.where,则会非常简单:

In [172]: arr = np.random.randn(4, 4)
In [173]: arr
Out[173]: 
array([[-0.5031, -0.6223, -0.9212, -0.7262],
       [ 0.2229,  0.0513, -1.1577,  0.8167],
       [ 0.4336,  1.0107,  1.8249, -0.9975],
       [ 0.8506, -0.1316,  0.9124,  0.1882]])
In [174]: arr > 0
Out[174]: 
array([[False, False, False, False],
       [ True,  True, False,  True],
       [ True,  True,  True, False],
       [ True, False,  True,  True]], dtype=bool)
In [175]: np.where(arr > 0, 2, -2)  #传递给where的数组大小可以不相等,甚至可以是标量值。
Out[175]: 
array([[-2, -2, -2, -2],
       [ 2,  2, -2,  2],
       [ 2,  2,  2, -2],
       [ 2, -2,  2,  2]])

四、数学和统计方法

在多维数组中,累加函数(如cumsum)返回的是同样大小的数组,但是会根据每个低维的切片沿着标记轴计算部分聚类: 

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

In [187]: arr
Out[187]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

In [188]: arr.cumsum(axis=0) #按行累加
Out[188]: 
array([[ 0,  1,  2],
       [ 3,  5,  7],
       [ 9, 12, 15]])

In [189]: arr.cumprod(axis=1)  #按列累乘
Out[189]: 
array([[  0,   0,   0],
       [  3,  12,  60],
       [  6,  42, 336]])
```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值