Python中各种小方法汇总

Content:

1. 确定列表中出现最多的元素

2. 高效计算L2范数

3. numpy.array花式索引

4. numpy矩阵分块求和


1. 确定列表中出现最多的元素

源地址在StackOverflow:https://stackoverflow.com/questions/1518522/find-the-most-common-element-in-a-list

    代码如下:

def most_common(lst):
    return max(set(lst), key=lst.count)

方法:集合set函数确定列表lst中的个元素。builtin函数count计算元素出现次数,并作为max函数的依据。然后最后用max找  到最频繁出现的值。

此中集合set(lst)可以被替换为lst,对于unhashable的内容同样奏效,但是这样会让计算速度变慢,不过对于大部分应用无关紧要。

2. 高效计算L2范数(无for循环)

m = x.shape[0] # x has shape (m, d)
n = y.shape[0] # y has shape (n, d)
x2 = np.sum(x**2, axis=1).reshape((m, 1))
y2 = np.sum(y**2, axis=1).reshape((1, n))
xy = x.dot(y.T) # shape is (m, n)
dists = np.sqrt(x2 + y2 - 2*xy) # shape is (m, n)

计算范数,dists[m,n]最后存储的是x中m行于y中n行的L2距离

3. numpy.array花式索引

Fancy indexing is conceptually simple: it means passing an array of indices to access multiple array elements at once. For example, consider the following array:

In [1]:
import numpy as np
rand = np.random.RandomState(42)

x = rand.randint(100, size=10)
print(x)
[51 92 14 71 60 20 82 86 74 74]

Suppose we want to access three different elements. We could do it like this:

In [2]:
[x[3], x[7], x[2]]
Out[2]:
[71, 86, 14]

Alternatively, we can pass a single list or array of indices to obtain the same result:

In [3]:
ind = [3, 7, 4]
x[ind]
Out[3]:
array([71, 86, 60])

When using fancy indexing, the shape of the result reflects the shape of the index arrays rather than the shape of the array being indexed:

In [4]:
ind = np.array([[3, 7],
                [4, 5]])
x[ind]
Out[4]:
array([[71, 86],
       [60, 20]])

Fancy indexing also works in multiple dimensions. Consider the following array:

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

Like with standard indexing, the first index refers to the row, and the second to the column:

In [6]:
row = np.array([0, 1, 2])
col = np.array([2, 1, 3])
X[row, col]
Out[6]:
array([ 2,  5, 11])

Notice that the first value in the result is X[0, 2], the second is X[1, 1], and the third is X[2, 3]. The pairing of indices in fancy indexing follows all the broadcasting rules that were mentioned in Computation on Arrays: Broadcasting. So, for example, if we combine a column vector and a row vector within the indices, we get a two-dimensional result:

In [7]:
X[row[:, np.newaxis], col]
Out[7]:
array([[ 2,  1,  3],
       [ 6,  5,  7],
       [10,  9, 11]])
In [8]:
row[:, np.newaxis] * col
Out[8]:
array([[0, 0, 0],
       [2, 1, 3],
       [4, 2, 6]])

It is always important to remember with fancy indexing that the return value reflects the broadcasted shape of the indices, rather than the shape of the array being indexed.

Combined Indexing

For even more powerful operations, fancy indexing can be combined with the other indexing schemes we've seen:

In [9]:
print(X)
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

We can combine fancy and simple indices:

In [10]:
X[2, [2, 0, 1]]
Out[10]:
array([10,  8,  9])

We can also combine fancy indexing with slicing:

In [11]:
X[1:, [2, 0, 1]]
Out[11]:
array([[ 6,  4,  5],
       [10,  8,  9]])

And we can combine fancy indexing with masking:

In [12]:
mask = np.array([1, 0, 1, 0], dtype=bool)
X[row[:, np.newaxis], mask]
Out[12]:
array([[ 0,  2],
       [ 4,  6],
       [ 8, 10]])

All of these indexing options combined lead to a very flexible set of operations for accessing and modifying array values.

4. numpy矩阵分块求和

用最简单的循环语句做出来的效果是:

In [1]: test=np.arange(81).reshape(9,9)
In [2]: res=np.zeros((3,3))
In [3]: for i in range(3):
      ...:     for j in range(3):
      ...:         res[i,j]=test[3*i:3*(i+1),3*j:3*(j+1)].mean()
In [4]: res
Out[5]: 
array([[ 10.,  13.,  16.],
       [ 37.,  40.,  43.],
       [ 64.,  67.,  70.]])

等价于:

In []: test.reshape(3,3,3,3).mean(axis=(1,3))
Out[]: 
array([[ 10.,  13.,  16.],
       [ 37.,  40.,  43.],
       [ 64.,  67.,  70.]])

是不是很神奇

或者这样也行,重复式的坐标轴表示法:

test.reshape(3,3,3,3).mean(3).mean(1)

如果是三维数组可以这样:

test.reshape( 2,3,3,3,3).mean((2,4))
test.reshape(-1,3,3,3,3).mean((2,4))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值