Numpy100道练习题+注解

Numpy是Python中一个用作数据分析的包,此处是GitHub中入门numpy的100道练习题。自己在动手时添加了一些注释

# 1 导入numpy
from numpy.lib import stride_tricks
import pandas as pd
import scipy.spatial as quick
import os
from numpy.lib.function_base import meshgrid
from numpy.core.function_base import linspace
import numpy as np

# 打印numpy的版本及配置信息
print(np.__version__)
print(np.show_config())

# 创建一个长度为10的空向量
Z = np.zeros(10)
print(Z)

# 找到任意数据的内存大小
Z = np.zeros((10, 10))
print("%d bytes" % (Z.size * Z.itemsize))

# 得到numpy的add说明文档
np.info(np.add)

# 创建一个第五个值为0的1向量
Z = np.ones(10)
Z[4] = 0
print(Z)

# 创建值域范围的数组
Z = np.arange(10, 30)
print(Z)

# 反转数组
Z = Z[::-1]
print(Z)

# 查找非零元素位置索引
NZ = np.nonzero([1, 2, 0, 0, 1, 2])
print(NZ)

# 创建一个3x3的矩阵,值为0-8
Z = np.arange(0, 9).reshape(3, 3)
print(Z)

# 创建一个3x3的单位矩阵
Z = np.eye(3)
print(Z)

# 创建一个3x3x3的随机矩阵
Z = np.random.random((3, 3, 3))
print(Z)

# 创建10x10x10的数组
Z = np.random.random((10, 10))
#Z = [Z.min(),Z.max()];
# print(Z);
Zmin, Zmax = Z.min(), Z.max()
print(Zmin, Zmax)

# 创建长度为30的随机向量并找到它的平均值
Z = np.random.random(30)
Z_mean = Z.mean()
print(Z_mean)

# 创建一个二维数组,其中边界值为1,其余值为0
Z = np.ones((10, 10))
Z[1:-1, 1:-1] = 0
print(Z)

# 对于一个存在数组,如何对边界添加0
Z = np.ones((5, 5))
Z = np.pad(Z, pad_width=1, mode='constant', constant_values=0)
print(Z)

# NaN = not a number, inf = infinity
# 表达式                #结果
0*np.nan  # nan
np.nan = np.nan  # False
np.inf > np.nan  # False
np.nan - np.nan  # nan
0.3 == 3*0.1  # False

# 创建一个5x5的数组,并设置1,2,3,4落在对角线下方
Z = np.diag(1 + np.arange(4), k=-1)
print(Z)

# 创建一个8x8的矩阵,并且设置为棋盘模式
Z = np.zeros((8, 8), dtype=int)
Z[1::2, ::2] = 1
Z[::2, 1::2] = 1
print(Z)

# 考虑一个(6,7,8)形状的数组,其第100个元素的索引(x,y,z)是什么
Z = np.unravel_index(100, (6, 7, 8))
print(Z)

# 用tile函数创建一个8x8的棋盘矩阵
Z = np.tile(np.array([[0, 1], [1, 0]]), (4, 4))
print(Z)

# 对于一个5x5的矩阵做归一化:(x-min)/(max-min)
Z = np.random.random((5, 5))
Z_max, Z_min = Z.max(), Z.min()
Z = (Z - Z_min) / (Z_max - Z_min)
print(Z)


# 创建一个颜色描述为(RGBA)四个无符号字符的自定义dtype
color = np.dtype([("r", np.ubyte, 1),
                  ("g", np.ubyte, 1),
                  ("b", np.ubyte, 1),
                  ("a", np.ubyte, 1)])
print(color)

# 一个5x3的矩阵和一个3x2的矩阵相乘,实矩阵乘积是?
Z = np.dot(np.ones((5, 3)), np.ones((3, 2)))
print(Z)

# 给定一个数组,对其在3和8之间的所有元素取反
Z = np.arange(11)
Z[(3 < Z) & (Z <= 8)] *= -1
print(Z)

# 下面脚本运行结果
print(sum(range(5), -1))  # 9
print(sum(range(5), -1))  # 10

# 考虑一个整数向量Z,下列表达合法的是哪个
# Z**Z        #True
# 2<>2     #False
# Z < -Z      #True
# 1j*Z        #True   #复数
#
# Z/1/1       #True
# Z < Z >Z    #False

# 下面表达式的结果分别是多少?
# np.array(0)/np.array(0)  #NAN
# np.array(0) // np.array(0)  #0
# np.array([np.nan]).astype((int).astype(float) - 2.14748365e+09)

# 如何从零位开始弃入浮点数组?
Z = np.random.uniform(-10, +10, 10)
print(np.copysign(np.ceil(np.abs(Z)), Z))

# 如何找出两个数组公共的元素?
Z1 = np.random.randint(0, 10, 10)
Z2 = np.random.randint(0, 10, 10)
print(np.intersect1d(Z1, Z2))

# 如何忽略所有的numpy警告
defaults = np.seterr(all="ignore")
Z = np.ones(1)

# Back to sanity
_ = np.seterr(**defaults)

# 另一个等价的方式,使用上下文管理器
# with np.errstate(divide = 'ignore')
#     Z = np.ones(1) / 0

# 下面的表达式是否为真
# np.sqrt(-1) == np.emath.sqrt(-1);       #False

# 如何获得昨天,今天和明天的日期?
yesterday = np.datetime64('today', 'D') - np.timedelta64(1, 'D')
today = np.datetime64('today', 'D')
tomorrow = np.datetime64('today', 'D') + np.timedelta64(1, 'D')

# 怎么获得所有与2016年7月的所有日期
Z = np.arange('2016-07', '2016-08', dtype='datetime64[D]')
print(Z)

# 如何计算((A+B)*(-A、2))(不使用中间变量)
Z = np.arange('2016-07', '2016-08', dtype='datetime64[D]')
print(Z)

# 用5种不同的方法提取随机数组中的整数部分
Z = np.random.uniform(0, 10, 10)
print(Z-Z % 1)
print(np.floor(Z))
print(np.ceil(Z)-1)
print(Z.astype(int))
print(np.trunc(Z))

# 创建一个5x5的矩阵且每一行的值范围为从0到4
Z = np.zeros((5, 5))
Z += np.arange(5)
print(Z)

# 如何用一个生成10个整数的函数来构建数组


def generate():
    for x in range(10):
        yield x


Z = np.fromiter(generate(), dtype=float, count=-1)
print(Z)

# 创建一个大小为10的向量,值域为0到1,不包括0和1
Z = np.linspace(0, 1, 12, endpoint=True)[1:-1]
print(Z)

# 创建一个大小为10的随机向量,并把它排序
Z = np.random.random(10)
Z.sort()
print(Z)

# 对一个小数组进行求和有没有办法比np.sum更快
Z = np.arange(10)
np.add.reduce(Z)
# np.add.reduce是numpy.add模块中的一个ufunc(universal function)函数,c语言实现

# 如何判断两和随机数组相等
A = np.random.randint(0, 2, 5)
B = np.random.randint(0, 2, 5)
# 假设array的形状(shape)相同和一个误差容限
equal = np.allclose(A, B)
print(equal)

# 把数组变为只读
Z = np.zeros(5)
Z.flags.writeable = False
#Z[0] = 1;

# 将一个10x2的笛卡尔坐标矩阵转换为极坐标
Z = np.random.random((10, 2))
X, Y = Z[:, 0], Z[:, 1]
R = np.sqrt(X**2 + Y**2)
T = np.arctan2(Y, X)
print(R)
print(T)

# 创建一个大小为10的随机向量并将
# 其中最大值替换为0
Z = np.random.random(10)
Z[Z.argmax()] = 0
print(Z)

# 创建一个结构化数组,其中x和y坐标覆盖[0,1]x[1,0]区域
Z = np.zeros((5, 5), [('x', float), ('y', float)])
Z['x'], Z['y'] = np.meshgrid(np.linspace(0, 1, 5), np.linspace(0, 1, 5))
print(Z)

# 给定两个数组x和y,构造柯西矩阵
X = np.arange(8)
Y = X + 0.5
C = 1.0 / np.subtract.outer(X, Y)
print(C)
print(np.linalg.det(C))  # 计算行列式

# 打印每个类型的numppy的最大和最小可表示值
for dtype in [np.int8, np.int32, np.int64]:
    print(np.iinfo(dtype).min)
    print(np.iinfo(dtype).max)
for dtype in [np.float32, np.float64]:
    print(np.finfo(dtype).min)
    print(np.finfo(dtype).max)
    print(np.finfo(dtype).eps)

# 如何打印数组中所有值
# np.set_printoptions(threshold = np.nan);
Z = np.zeros((16, 16))
print(Z)

# 如何在数组中找出与给定标量接近的值
Z = np.arange(100)
V = np.random.uniform(0, 100)
index = (np.abs(Z-V)).argmin()
print(Z[index])


# //思考形状如(100,2)的随机向量,求出点与点之间的距离
# //(提示:np.atleast_2d,T,np.sqrt)
z = np.random.random((100, 2))
X, Y = np.atleast_2d(z[:, 0], z[:, 1])
D = np.sqrt((X-X.T)**2+(Y-Y.T)**2)
print(D)

# 使用scipy库更加快速
D = quick.distance.cdist(z, z)
print(D)

# 如何将一个32位float数组转换为32位int数组
z = np.arange(10, dtype=np.int32)
z = z.astype(np.float32, copy=False)
print(z)

# 如何读取下面的文件(np.genfromtxt)
z = np.genfromtxt("example.txt", delimiter=",")
print(z)

# numpy数组枚举(enumerate)的等价操作
# 提示:np.ndenumerate,np.ndindex
z = np.arange(9).reshape(3, 3)  # 单行数组变换为3x3数组
for index, value in np.ndenumerate(z):
    print(index, value)

for index in np.ndindex(z.shape):
    print(index, z[index])

# 构建一个二维高斯矩阵(np.meshgrid,np.exp)
X, Y = np.meshgrid(np.linspace(-1, 1, 10), np.linspace(-1, 1, 10))
D = np.sqrt(X**2+Y**2)
sigma, mu = 1.0, 0.0
G = np.exp(-((D-mu)**2/(2.0*sigma**2)))
print(G)

# 在二维数组的随机位置放置p个元素(np.put,np.random.choice)
n = 5
p = 3
z = np.zeros((n, n))
np.put(z, np.random.choice(range(n*n), p, replace=False), 1)
print(z)

# 减去矩阵每一行的平均值(mean(axis=,keepdims=))
x = np.random.rand(3, 4)
# 新
Y = x - x.mean(axis=1, keepdims=True)
# 旧
Y = x - x.mean(axis=1).reshape(-1, 1)
print(X, Y)

# 如何对数组第n列进行排序
z = np.random.randint(0, 10, (5, 3))
print(z)
print(z[z[:, 0].argsort()])

# 如何判断一个给定的数组存在空列
z = np.random.randint(0, 3, (3, 10))
print((~z.any(axis=0)).any())

# 从数组找出与给定值最接近的值(np.abs,argmin,flat)
Z = np.random.uniform(0, 1, 10)
z = 0.5
m = Z[np.abs(Z-z).argmin()]
print(m)

# 形状如(1,3)和形状如(3,1)的两个数组形状,如何使用迭代器计算他们的和
A = np.arange(3).reshape(3, 1)
B = np.arange(3).reshape(1, 3)
it = np.nditer([A, B, None])
for x, y, z in it:
    z[...] = x+y
print(it.operands[2])

# 创建一个具有name属性的数组类


class NamedArray (np.ndarray):
    def __new__(cls, array, name="no name"):
        obj = np.asarray(array).view(cls)
        obj.name = name
        return obj

    def __array_finalize__(self, obj):
        if obj is None:
            return
        self.info = getattr(obj, 'name', "no name")


Z_name = NamedArray(np.ones(10), "range_10")
print(Z_name.name)

# 给定一个向量,如何让在第二个向索引的每个元素加1(注意重复索引)(提示:np.biincount | np.add.at)
Z = np.ones(10)
I = np.random.randint(0, len(Z), 20)
Z += np.bincount(I, minlength=len(Z))
print(Z)

np.add.at(Z, I, 1)
print(Z)

# 如何根据索引列表I将向量X的元素累加到数组F中(提示:np.bincount)
X = [1, 3, 3, 3, 4, 1]
I = [1, 3, 3, 3, 4, 1]
F = np.bincount(I, X)  # 数组I长度中各个数据重复值,将重复值带入X(类似各个数据节点对应权值)中相加为结果
print(F)

# 思考(dtype=ubyte)的(w,h,3)图像,计算唯一颜色的数量
w, h = 16, 16
I = np.random.randint(0, 3, (h, w, 3)).astype(np.ubyte)
F = I[..., 0]*256*256 + I[..., 1]*256 + I[..., 2]
n = len(np.unique(F))
print(n)

# 考虑一个四维数组如何一次计算最后两个轴(axis)的和(提示:sum(axis=(-2,-1)))
A = np.random.randint(0, 10, (3, 4, 3, 4))
sum = A.sum(axis=(-2, -1))
print(sum)
# 方法二
sum = A.reshape(A.shape[:-2]+(-1,)).sum(axis=-1)
print(sum)

# 给定一个一维向量D,如何使用相同大小的向量S来计算D子集的均值(提示:np.bincount)
D = np.random.uniform(0, 1, 100)
S = np.random.randint(0, 10, 100)
D_sums = np.bincount(S, weights=D)
D_counts = np.bincount(S)
D_means = D_sums/D_counts
print(D_means)
# 方法二
print(pd.Series(D).groupby(S).mean())

# 如何获得点积dot product的对角线(提示:np.diag)
A = np.random.uniform(0, 1, (5, 5))
B = np.random.uniform(0, 1, (5, 5))
# slow version
w = np.diag(np.dot(A, B))
# 方法2
# Fast version
np.sum(A*B.T, axis=1)
# 方法3
# Faster version
np.einsum("ij,ji->i", A, B)

# 考虑一个向量【1,2,3,4,5】,如何建立一个新的向量,在这个新的向量中每个值之间有3个连续的零(array[::4])
z = np.array([1, 2, 3, 4, 5])  # np.arange(1,6)
nz = 3
z0 = np.zeros(len(z)+(len(z)-1)*(nz))
z0[::nz+1] = z  # 间隔4插入z
print(z0)

# 考虑一个 (5,5,3)的数组,如何将其与一个(5,5)数组相乘(提示:array[:,:,None])
A = np.random.randint(1, 4, (5, 5, 3))
B = 2*np.ones((5, 5))
print(A*B[:, :, None])

# 如何对一个数组中任意两行做交换(array[[]] = array[[]])
A = np.arange(25).reshape(5, 5)
A[[0, 1]] = A[[1, 0]]
print(A)

# 考虑一个可以描述10个三角形的triplets,找到可以分割全部三角形的line segment(提示:repeat,np.roll,np.sort,view,np.unique)
faces = np.random.randint(0, 100, (10, 3))
"""
numpy.roll(a,shift,axis=None)沿着给定轴滚动数组元素。超出最后位置的元素将会回滚到第一个位置
将a沿着axis方向滚动shift长度 a:输入数组 shift:滚动长度(若为元组则轴也为元组) 
axis:滚动轴 0为垂直滚动,1为水平滚动(若为None则数组在移位前扁平化,之后恢复原状)
输出与a维度一致

numpy.repaet(a,num,axis=None)沿着给定轴复制数组元素num次,会增加原数组维度
axis=None:扁平化,每个元素复制num次
axis=0:沿着列方向复制,每行元素复制num次
axis=1:沿着行方向复制,每列元素复制num次

numpy.ndarray.view函数对内存区域不同的切割方式,来完成数据类型的转换,无需对数据进行额外的copy
但内存需要连续

a,b,c = numpy.unique(A,return_index=True,return_inverse=True)函数取出原数组中重复元素,并按照元素由大到小返回新元组或列表
a:无重复元素的新数组
b:新数组元素在原数组中位置
c:旧数组元素在新数组中位置
"""

F = np.roll(faces.repeat(2, axis=1), -1, axis=1)
F = F.reshape(len(F)*3, 2)
"""
np.sort函数:按照行进行排序
axis=0:按照列进行排序
axis=1:按照行进行排序
默认按照行进行排序
"""
F = np.sort(F, axis=1)
"""
view函数用法
"""
G = F.view(dtype=[('p0', F.dtype), ('p1', F.dtype)])
D = np.unique(G)
print(G)

# 给定一个二进制的数组C,如何产生一个数组A满足np.bincount(A)==C
C = np.bincount([1, 1, 2, 3, 4, 4, 6])
A = np.repeat(np.arange(len(C)), C)
print(A)

# 如何通过滑动窗口计算一个数组的平均数(提示:np.cumsum)
"""
np.cumsum 数组累加
"""


def moving_average(a, n=3):
    ret = np.cumsum(a, dtype=float)
    ret[n:] = ret[n:]-ret[:-n]
    return ret[n - 1:]/n


Z = np.arange(20)
print(moving_average(Z, n=3))

# 思考一维数组Z,构建一个二维数组,其第一行是(Z[0],Z[1],Z[2]),然后每一行移动一位,最后一行为(Z[-3],Z[-2],Z[-1])提示:from numpy.lib import stride_tricks
"""
stride_tricks.as_strided(x,shape=None,strides=None,subok=False,writeable=True)

np.itemsize()数组中每个元素字节长度
"""


def rolling(a, window):
    shape = (a.size - window + 1, window)
    strides = (a.itemsize, a.itemsize)
    return stride_tricks.as_strided(a, shape=shape, strides=strides)


Z = rolling(np.arange(10, dtype=np.int8), 3)
print(Z)

# 如何对bool值取反,或者原位(in-place)改变浮点数的符号(sign)提示:np.logical_not,np.negative
Z = np.random.randint(0, 2, 100)
np.logical_not(Z, out=Z)

Z = np.random.uniform(-1.1, 1.0, 100)
np.negative(Z, out=Z)

# 考虑两组点集P0和P1去描述一组栈(二维)和一个点p,如何计算点p到每一条线i(P0[i],P1[i])的垂直距离
"""
numpy.sum(a,axis=None,,dtype=None,out=None,keepdim=np._NoValue)函数中
a:用于计算加法性质的数组
axis:None表示所有元素直接相加;0:每列元素相加 1:每行元素相加
axis为整数元组(x,y),则是求axis=x和axis=y情况下得到的和值
keepdim=True:确保矩阵在进行行列压缩运算之后矩阵维度保持不变
"""


def distance(P0, P1, p):
    T = P1 - P0
    L = (T**2).sum(axis=1)
    U = -((P0[:, 0]-p[..., 0])*T[:, 0]+(P0[:, 1]-P[..., 1])*T[:, 1])/L
    U = U.reshape(len(U), 1)
    D = P0 + U*T - P
    return np.sqrt((D**2).sum(axis=1))


P0 = np.random.uniform(-10, 10, (10, 2))
P1 = np.random.uniform(-10, 10, (10, 2))
P = np.random.uniform(-10, 10, (1, 2))  # 一个点
print(distance(P0, P1, P))

# 点集p到P0与P1连线的距离
P = np.random.uniform(-10, 10, (10, 2))
print(np.array([distance(P0, P1, P) for P_i in P]))

# 思考一个任意维数组,编写一个函数,该函数提取一个具有固定形状的子部分,并以给定元素为中心(在该部分填充)
# 提示:minimum,maximum
"""
numpy.max:(a,axis=None,out=None,keepdims=False)默认为列向取值
numpy.maximum:(X,Y,out=None)~X,Y逐位进行比较,取较大者,最少接收两个参数(Y可为单一元素)
numpy.minimum:
slice:(start,end)~可以提取字符串的某个部分,并以新的字符串返回被提取的部分
zip:([iterable,...]) iterable为可迭代的对象,并且可以有多个参数。该函数返回一个以元组为元素的列表,
其中第i个元组包含每个参数序列的第i个元素。返回的列表长度被截断为最短的参数序列长度。只有一个序列参数时,
它返回一个一元组的列表,没有参数时,返回空列表

"""
Z = np.random.randint(0, 10, (10, 10))
shape = (5, 5)
fill = 0
position = (1, 1)
R = np.ones(shape, dtype=Z.dtype)*fill
P = np.array(list(position)).astype(int)
Rs = np.array(list(R.shape)).astype(int)
Zs = np.array(list(Z.shape)).astype(int)

R_start = np.zeros((len(shape),)).astype(int)
R_stop = np.array(list(shape)).astype(int)
Z_start = (P-Rs//2)
Z_stop = (P+Rs//2)+Rs % 2

R_start = (R_start - np.minimum(Z_start, 0)).tolist()
Z_start = (np.maximum(Z_start, 0)).tolist()
R_stop = np.maximum(R_start, (R_stop-np.maximum(Z_stop-Zs, 0))).tolist()
Z_stop = (np.minimum(Z_stop, Zs)).tolist()

r = [slice(start, stop) for start, stop in zip(R_start, R_stop)]
z = [slice(start, stop) for start, stop in zip(Z_start, Z_stop)]
R[r] = Z[z]
print(Z)
print(R)

# 考虑一个数组Z=[1,2,3,4,5,6,7,8,9,10,11,12,13,14],如何生成一个
# 数组R=[[1,2,3,4],[2,3,4,5],[3.4.5.6],..,[11,12,13,14]] 提示:stride_tricks.as_strided()
"""
stride_tricks.as_strided(a,shape=None,strides=None) 移动步长按照字节进行计算
"""
Z = np.arange(1, 15, dtype=np.uint32)
R = stride_tricks.as_strided(Z, (11, 4), (4, 4))
print(R)

# 计算一个矩阵的秩 提示:np.linalg.svd
"""
U,S,V=numpy.linalg.svd(a,full_matrices=1,compute_uv=1
参数:
a是一个形如(M,N)矩阵
full_matrices的取值是为0或者1,默认值为1,这时u的大小为(M,M),v的大小为(N,N)。
否则u的大小为(M,K),v的大小为(K,N) K=min(M,N)
compute_uv的取值是为0或者1,默认值为1,表示计算u,s,v。为0的时候只计算s
a = U*S*V
S为奇异值分解,对角元素为奇异值,按从大到小排列,其他元素均为0.
"""
Z = np.random.uniform(0, 1, (10, 10))
U, S, V = np.linalg.svd(Z)
rank = np.sum(S > 1e-10)
print(rank)

# 如何找到一个数组中频率最高的值
Z = np.random.randint(0, 10, 50)
print(np.bincount(Z).argmax())

# 从一个10x10的矩阵中提取出连续的3x3的区块 提示:stride_tricks.as_strided
Z = np.random.randint(0, 5, (10, 10), dtype=np.uint32)
n = 3
i = 1 + (Z.shape[0]-3)
j = 1 + (Z.shape[1]-3)
C = stride_tricks.as_strided(
    Z, shape=(i, j, n, n), strides=Z.strides+Z.strides)
print(C)

# 创建一个Z[i,j] = Z[i,j]的子类 提示:class方法
"""

"""


class Symetric(np.ndarray):
    def __setitem__(self, index, value):
        i, j = index
        super(Symetric, self).__setitem__((i, j), value)
        super(Symetric, self).__setitem__((j, i), value)


def symetric(Z):
    return np.asarray(Z+Z.T-np.diag(Z.diagonal())) .view(Symetric)


S = symetric(np.random.randint(0, 10, (5, 5)))

print(S)

# 对于一个16x16的数组,如何得到一个区域(block-sum)的和(区域大小为4x4)提示:np.add.reduceat
"""
np.add.reduceat:通过列表indices参数(列表形式)指定一系列插入reduce的起始和终止位置(reduce at).
规则:如果indice中某元素小于其后面元素,则相应结果为这两个元素位置产生的slice里的数组元素。对于最后一个元素
因为其后再无其他元素,结果为对所有元素进行reduce
"""
Z = np.ones((16, 16))
K = 4
S = np.add.reduceat(np.add.reduceat(Z, np.arange(0, Z.shape[0], K), axis=0),
                    np.arange(0, Z.shape[1], K), axis=1)
print(S)

# 如何利用numpy实现Game of life 提示:game of life


def iterate(Z):
    # Count number
    N = (Z[0:-2, 0:-2]+Z[0:-2, 1:-1]+Z[0:-2, 2:] +
         Z[1:-1, 0:-2] + Z[1:-1, 2:] +
         Z[2:, 0:-2]+Z[2:, 1:-1]+Z[2:, 2:])
    # Apply rule
    birth = (N == 3) & (Z[1:-1, 1:-1] == 0)
    survive = ((N == 2) | (N == 3)) & (Z[1:-1, 1:-1] == 1)
    Z[...] = 0
    Z[1:-1, 1:-1][birth | survive] = 1
    return Z


Z = np.random.randint(0, 2, (50, 50))
for i in range(100):
    Z = iterate(Z)
print(Z)

# 如何找到一个数组的第n个最大值 提示:np.argsort|np.argpartition
"""
numpy.shuffle:对数组进行随机排序
numpy.argsort:对数据进行排序
np.argpartition:排序数组,在前面的小于该索引处值,后面大于
"""
Z = np.arange(10000)
np.random.shuffle(Z)
n = 5
# slow
print(Z[np.argsort(Z)[-n:]])
# Fast
print(Z[np.argpartition(-Z, n)[:n]])

# 给定任意个数向量,创建笛卡尔积(每一个元素的每一种组合)
"""
numpy.indices:数组切片
enumerate:枚举对象,索引加数据值
"""


def cartesian(arrays):
    arrays = [np.asarray(a) for a in arrays]
    shape = (len(x) for x in arrays)
    ix = np.indices(shape, dtype=int)
    ix = ix.reshape(len(arrays), -1).T
    for n, arr in enumerate(arrays):
        ix[:, n] = arrays[n][ix[:, n]]
    return ix


print(cartesian(([1, 2, 3], [4, 5], [6, 7])))

# 如何从一个正常数组创建记录数组(record array) 提示:np.core.records.fromarrays
"""
np.core.records.fromarrays(arrayList,dtype=None,shape=None,formats=None,names=None,title=None,aligned=False,byteorder=none)[source]:
arrayList:list或tuple类数组对象的列表(例如:列表,元组和ndarray)
dtype:data-type,可选所有数组的有效dtype
shape:int或ints的tuple,可选所得数组的Shape。如果未提供,则从arrayList[0]推断
formates,names,titles,aligned,byteorder:如果dtype为None,则从这些参数传递给numpy,format_parser以构建dtype
返回值:np.recarry记录由给定的arrayList列组成的数组
"""
Z = np.array([("Hello", 2.5, 3),
              ("World", 3.6, 2)])
R = np.core.records.fromarrays(Z.T,
                               names='col1,col2,col3',
                               formats='S8,f8,i8')
print(R)

# 考虑一个大向量,考虑如何用三种不同方式计算它的立方 提示:np.power,*,np.einsum
x = np.random.rand()
np.power(x, 3)
# 方式2
x*x*x
# 方式3
np.einsum('i,i,i->i', x, x, x)

# 考虑两个形状分别为(8,3)和(2,2)的数组A,B,如何在数组A中找到满足包含B中元素的行(不包含B中每行元素顺序)提示:np.where
"""
np.where(condition,x,y):满足条件(condition),输出x,不满足输出y
np.where(condition):只有条件(condition),没有x和y。则输出满足条件(即:非0)元素的坐标,这里坐标以tuple的形式输出,通常原数组几维,
输出的tuple中包含几个数组,分别对应符合条件元素的各维坐标
np.newaxis:增加矩阵维度
"""
A = np.random.randint(0, 5, (8, 3))
B = np.random.randint(0, 5, (2, 2))
C = (A[..., np.newaxis, np.newaxis] == B)
rows = np.where(C.any((3, 1)).all(1))[0]
print(rows)

# 考虑一个10x3的矩阵,分解出有不完全相同值的行
Z = np.random.randint(0, 5, (10, 3))
print(Z)
# solution for array of all dtype(including string arrays and record arra)
E = np.all(Z[:, 1:] == Z[:, :-1], axis=1)
U = Z[~E]
print(U)
# 方法二
# solution for numerical arrays only, will work for any number of columns in
U = Z[Z.max(axis=1) != Z.min(axis=1), :]
print(U)

# 将一个整数向量转换为matrix binary的表现形式 提示:np.unpackbits
"""
np.unpackbits:整数转换为2进制
"""
I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128], dtype=np.uint8)
B = ((I.reshape(-1, 1) & (2*np.arange(8))) != 0).astype(int)
print(B[:, ::-1])
# 方法二
# print(np.unpackbits(I[:,np.newaxis],axis=1))
print(np.unpackbits(I.reshape(-1, 1), axis=0))

# 给定一个二维数组,如何提取出唯一的(unique)行  提示:np.ascontiguousarray
"""
np.ascontiguousarray():将内存不连续数组转换为内存连续数组
"""
Z = np.random.randint(0, 2, (6, 3))
T = np.ascontiguousarray(Z).view(
    np.dtype((np.void, Z.dtype.itemsize*Z.shape[1])))
_, idx = np.unique(T, return_index=True)
uZ = Z[idx]
print(uZ)

# 考虑两个向量A和B,写出用einsum等式对应的inner,outer,sum,mul函数 提示:np.einsum
"""
np.einsum函数:爱因斯坦求和约定操作指定在numpy中的运算

"""
# A和B是两个形状兼容的一维数组(相应的轴的长度要么相等,要么其中一个长度为1)
A = np.random.randint(1, 2, 10)
B = np.random.randint(1, 2, 10)
print("返回数组A的视图")
print(np.einsum('i', A))  # A
print('数组A的总和')
print(np.einsum('i->', A))  # np.sum(A)
print('A和B的数组元素依次相乘')
print(np.einsum('i,i->i', A, B))  # A*B
print('A和B的点积(内积)inner')
print(np.einsum('i,i', A, B))  # np.inner(A,B)
print('A和B的外积(叉积)outer')
print(np.einsum('i,j->ij', A, B))  # np.outer(A,B)

# A和B为与之兼容的两个二维数组
A = np.random.randint(1, 2, 16).reshape(4, 4)
B = np.random.randint(1, 2, 16).reshape(4, 4)
print("返回A的视图")
print(np.einsum('ij', A))  # A
print("A的转置")
print(np.einsum('ji', A))  # A.T
print("A的主对角线")
print(np.einsum('ii->i', A))  # np.diag(A)
print("A的主对角线的和")
print(np.einsum('ii', A))  # np.trace(A)
print("A的值相加")
print(np.einsum('ij->', A))  # np.sum(A)
print("A的轴垂直(列)求和")
print(np.einsum('ij->j', A))  # np.sum(A,axis=0)
print("A的轴水平(行)求和")
print(np.einsum('ij->i', A))  # np.sum(A,axis=1)
print("A和B逐个元素依次相乘")
print(np.einsum('ij,ij->ij', A, B))  # A*B
print("A和B的转置逐个元素依次相乘")
print(np.einsum('ij,ji->ij', A, B))  # A*B.T
print("A和B的矩阵乘法")
print(np.einsum('ij,jk->ik', A, B))  # dot(A,B)
print("A和B的内积")
print(np.einsum('ij,kj->ik', A, B))  # inner(A,B)
print("A的每一行乘以B")
print(np.einsum('ij,kj->ikj', A, B))  # A[:,None]*B
print("A的每个值乘以B")
print(np.einsum('ij,kl->ijkl', A, B))  # A[:,:,None,None]*B

# 考虑一个由两个向量描述的路径(X,Y),如何用等距样例对其进行采样 提示:np.comsum np.interp
"""
np.comsum(a,axis):按照axis累加,不指定axis,则压缩为一维
np.interp(a,x,y):在a序列中插入横坐标x,纵坐标y的点
"""
phi = np.arange(0, 10*np.pi, 0.1)
a = 1
x = a*phi*np.cos(phi)
y = a*phi*np.sin(phi)
dr = (np.diff(x)**2 + np.diff(y)**2)**(1//2)  # 长度
r = np.zeros_like(x)
r[1:] = np.cumsum(dr)
r_int = np.linspace(0, r.max(), 200)
x_int = np.interp(r_int, r, x)        #
y_int = np.interp(r_int, r, y)

# 给定一个整数n和一个二维数组X,从X中选择可以被解释为从多n度的多项分布式的行,即这些行只包含整数对n的和 提示:np.logical_and.reduce,np.mod
"""
np.logical_and.reduce:逻辑运算符号
np.mod(a,b):相当于a%b,符号与b相同
"""
X = np.asarray([[1.0, 0.0, 3.0, 8.0],
                [2.0, 0.0, 1.0, 1.0],
                [1.5, 2.5, 1.0, 0.0]])
n = 4
M = np.logical_and.reduce(np.mod(X, 1) == 0, axis=-1)
M &= (X.sum(axis=-1) == n)  # -1表示倒数第一个(即最后一个维度)
print(X[M])

# 对于一个一维数组X,计算它boostrapped之后的95%置信区间的平均值 提示:np.percentile
"""
np.percentile:百分比分位数计算
"""
X = np.random.randn(100)  # 随机产生一个一维的array数组
N = 1000  # 样例
idx = np.random.randint(0, X.size, (N, X.size))
mean = X[idx].mean(axis=1)
confint = np.percentile(mean, [2.5, 97.5])
print(confint)

你可能感兴趣的:(python,python)