python之numpy模块的使用(3)典型案例

原文链接: https://www.numpy.org.cn/article/advanced/numpy_exercises_for_data_analysis.html

1、创建bool布尔数组

# 创建布尔数组;所有值为True
arr_bool = np.full([3, 3], True, dtype=bool)
print(arr_bool)

arr_bool2 = np.ones([3, 4], dtype=bool)
print(arr_bool2)

# 拓展: where函数的两个参数
arr = np.arange(10)
print(np.where(arr > 5)[0])
# [6 7 8 9]
print(np.where(arr > 5, True, False))
# [False False False False False False  True  True  True  True]

# 拓展 np.logical_and(条件1, 条件2)
arr = np.arange(10)
print(np.logical_and(arr > 5, arr < 100))
# [False False False False False False  True  True  True  True]

2、从一维数组中提取满足指定条件的元素

# 从arr中提取所有的奇数
arr = np.arange(10)
oddarr = arr[arr % 2 == 1]
print(oddarr)
# [1 3 5 7 9]

3、用一个值替换满足条件的数组元素项

# 将arr中的所有奇数替换为-1
arr = np.arange(10)
arr[arr % 2 == 1] = -1
print(arr)
# [ 0 -1  2 -1  4 -1  6 -1  8 -1]

# 拓展: 将arr中的所有奇数替换为-1,而不改变arr
arr = np.arange(10)
arr1 = np.where(arr % 2 == 1, -1, arr)
print(arr)
# [0 1 2 3 4 5 6 7 8 9]
print(arr1)
# [ 0 -1  2 -1  4 -1  6 -1  8 -1]

4、改变数组的形状reshape;参数为-1

# 将一维数组转换为2行的2维数组; 设置为-1将自动确定列数
np.arange(10).reshape(2, -1)

5、如何垂直叠加两个数组?

# 垂直堆叠二维数组a和二维数组b
a = np.arange(10).reshape(2, -1)
b = np.repeat(1, 10).reshape(2, -1)

# 方式1 若要水平叠加,令axis=1
ab1 = np.concatenate([a, b], axis=0)

# 方式2, 若要水平叠加,使用np.hstack([a, b])
ab2 = np.vstack([a, b])

# 方式3, 若要水平叠加,使用np.c_[a, b]
ab3 = np.r_[a, b]

print(ab1)
print(ab2)
print(ab3)
# [[0 1 2 3 4]
#  [5 6 7 8 9]
#  [1 1 1 1 1]
#  [1 1 1 1 1]]

# 拓展 在二维数组最后添加一列
a = np.array([1, 2, 3])
arr2d = np.arange(9).reshape(3, 3)
# 先将a 转化成列向量
a2 = a[:, np.newaxis]
# 将列向量a2与连接arr2d
arr2d_a2 = np.hstack([arr2d, a2])
print(arr2d_a2)
# [[0 1 2 1]
#  [3 4 5 2]
#  [6 7 8 3]]

6、repeat和tile的应用

a = np.array([1, 2, 3])
arr = np.r_[np.repeat(a, 3), np.tile(a, 3)]
print(arr)
# [1 1 1 2 2 2 3 3 3 1 2 3 1 2 3 1 2 3]

7、获取两个数组之间的公共项

# 获取数组a和数组b之间的公共项
a = np.array([1, 2, 3, 2, 3, 4, 3, 4, 5, 6])
b = np.array([7, 2, 10, 2, 7, 4, 9, 4, 9, 8])
con_ab = np.intersect1d(a, b)
print(con_ab)
# [2 4]

8、如何从一个数组中删除存在于另一个数组中的项?

# 从数组a中删除数组b中的所有项
a = np.array([1, 2, 3, 4, 5])
b = np.array([5, 6, 7, 8, 9])
a = np.setdiff1d(a, b)
print(a)
# [1 2 3 4]

9、如何得到两个数组元素匹配的位置?

# 获取a和b元素匹配的位置。
a = np.array([1, 2, 3, 2, 3, 4, 3, 4, 5, 6])
b = np.array([7, 2, 10, 2, 7, 4, 9, 4, 9, 8])
print(np.where(a == b)[0])
# [1 3 5 7]

10、创建一个python函数可以在numpy数组上运行

# 转换适用于两个标量的函数maxx,以处理两个数组。
def maxx(x, y):
    if x >= y:
        return x
    else:
        return y

pair_max = np.vectorize(maxx, otypes=[float])
a = np.array([5, 7, 9, 8, 6, 4, 5])
b = np.array([6, 3, 4, 8, 9, 7, 1])
c = pair_max(a, b)
print(c)
# [6. 7. 9. 8. 9. 7. 5.]

11、反转数组

# 只反转二维数组arr的行。
# 只反转二维数组的列可以使用arr[:, ::-1]
arr = np.arange(9).reshape(3, 3)
print(arr[::-1])
# [[6 7 8]
#  [3 4 5]
#  [0 1 2]]
# 反转整个数组
print(arr[::-1, ::-1])
# [[8 7 6]
#  [5 4 3]
#  [2 1 0]]

12、创建值在某区间内随机浮动的数组

# 创建一个形状为5x3的二维数组,以包含5到10之间的随机十进制数。
arr = np.arange(9).reshape(3, 3)
# Method 1:
rand_arr = np.random.randint(low=5, high=10, size=(5, 3)) + np.random.random((5, 3))
print(rand_arr)

# Method 2:
rand_arr = np.random.uniform(5, 10, size=(5, 3))
print(rand_arr)

13、set_printoptions设置打印样式

# 只打印或显示numpy数组rand_arr的小数点后3位。
rand_arr = np.random.random([5, 3])
np.set_printoptions(precision=3)
print(rand_arr[:4])
# [[0.827 0.931 0.351]
#  [0.209 0.944 0.037]
#  [0.22  0.823 0.764]
#  [0.233 0.574 0.272]]

# 通过e式科学记数法来打印rand_arr
# 将打印选项重置为默认值
np.set_printoptions(suppress=False)
rand_arr = np.random.random([3, 3]) / 1e3
print(rand_arr)
# [[5.434e-04 2.784e-04 4.245e-04]
#  [8.448e-04 4.719e-06 1.216e-04]
#  [6.707e-04 8.259e-04 1.367e-04]]

# 将numpy数组a中打印的项数限制为最多6个元素。
np.set_printoptions(threshold=6)
a = np.arange(15)
print(a)
# [ 0  1  2 ... 12 13 14]

# 打印完整的numpy数组a而不截断。
np.set_printoptions(threshold=6)
a = np.arange(15)
# error https://blog.csdn.net/UEVOLIshy/article/details/94916003
# np.set_printoptions(threshold=np.nan)
np.set_printoptions(threshold=999)
print(a)
# [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]

14、从元组数组中提取某一列

url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris_1d = np.genfromtxt(url, delimiter=',', dtype=None)
print(iris_1d)
species = np.array([row[4] for row in iris_1d])
print(species[:5])

15、将一维元组数组转化为二维numpy数组

iris_1d = np.genfromtxt('iris.data', delimiter=',', dtype=None)
# 方法1,将每一行转换为一个列表并获取前4项
iris_2d = np.array([row.tolist()[:4] for row in iris_1d])
# 打印转化后的二维numpy数组的前5行
print(iris_2d[:5])

# 方法2,仅从源导入前4列
iris_2d = np.genfromtxt('iris.data', delimiter=',', dtype='float', usecols=[0, 1, 2, 3])
# 打印转化后的二维numpy数组的前5行
print(iris_2d[:5])

16、如何计算numpy数组的均值,中位数,标准差?

# 求出鸢尾属植物萼片长度的平均值、中位数和标准差(第1列)
# 先提取要计算的一列
sepallength = np.genfromtxt('iris.data', delimiter=',', dtype='float', usecols=[0])
mu, med, sd = np.mean(sepallength), np.median(sepallength), np.std(sepallength)
print(mu, med, sd)

17、如何规范化数组,使数组的值正好介于0和1之间?

# 创建一种标准化形式的鸢尾属植物间隔长度,其值正好介于0和1之间,这样最小值为0,最大值为1
sepallength = np.genfromtxt('iris.data', delimiter=',', dtype='float', usecols=[0])
Smax, Smin = sepallength.max(), sepallength.min()
S = (sepallength - Smin)/(Smax - Smin)
print(S)
# or  ptp()表示最大值-最小值
S = (sepallength - Smin)/sepallength.ptp()
print(S)

18、如何找到numpy数组的百分位数?

sepallength = np.genfromtxt('iris.data', delimiter=',', dtype='float', usecols=[0])
print(np.percentile(sepallength, q=[5, 95]))
# [4.6   7.255]

19、如何在数组中的随机位置插入值?

# 在iris_2d数据集中的20个随机位置插入np.nan值
iris_2d = np.genfromtxt('iris.data', delimiter=',', dtype='object')
# Method 1
np.random.seed(100)
# i,j包含iris_2d所有元素的行号和列号
i, j = np.where(iris_2d)
# print(i, j)
iris_2d[np.random.choice((i), 20), np.random.choice((j), 20)] = np.nan
print(iris_2d[:10])

# Method 2 
np.random.seed(100)
iris_2d[np.random.randint(150, size=20), np.random.randint(4, size=20)] = np.nan
print(iris_2d[:10])

20、如何在numpy数组中找到缺失值的位置?

# 在iris_2d的sepallength中查找缺失值的数量和位置(第1列)
iris_2d = np.genfromtxt('iris.data', delimiter=',', dtype='object')
iris_2d[np.random.randint(150, size=20), np.random.randint(4, size=20)] = np.nan
print("缺失值个数: \n", np.isnan(iris_2d[:, 0]).sum())
print("缺失值位置: \n", np.where(np.isnan(iris_2d[:, 0])))

21、如何从numpy数组中删除包含缺失值的行?

iris_2d = np.genfromtxt('iris.data', delimiter=',', dtype='float', usecols=[0, 1, 2, 3])
iris_2d[np.random.randint(150, size=20), np.random.randint(4, size=20)] = np.nan
# print(iris_2d)
# Method 1: ~表示取反
any_nan_in_row = np.array([~np.any(np.isnan(row)) for row in iris_2d])
# print(any_nan_in_row) # 打印的是布尔型数组
# print(iris_2d[any_nan_in_row]) 打印的是剔除掉包含缺失值的行的矩阵
print(iris_2d[any_nan_in_row][:5])

# Method 2:
# print(np.isnan(iris_2d)) # 返回的是布尔型数组;false+false+false+false == 0
print(iris_2d[np.sum(np.isnan(iris_2d), axis=1) == 0][:5])

22、如何找到numpy数组的两列之间的相关性?

# 在iris_2d中找出SepalLength(第1列)和PetalLength(第3列)之间的相关性
iris_2d = np.genfromtxt('iris.data', delimiter=',', dtype='float', usecols=[0, 1, 2, 3])
# Solution 1
print(np.corrcoef(iris_2d[:, 0], iris_2d[:, 2])[0, 1])
# 0.8717541573048718

# Solution 2
from scipy.stats.stats import pearsonr
corr, p_value = pearsonr(iris_2d[:, 0], iris_2d[:, 2])
print(corr)
# 0.8717541573048713

23、如何查找给定数组是否具有任何空值?

url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris_2d = np.genfromtxt(url, delimiter=',', dtype='float', usecols=[0, 1, 2, 3])
print(np.isnan(iris_2d).any())
# False

24、如何在numpy数组中查找唯一值的计数?

# 找出鸢尾属植物物种中的独特值和独特值的数量
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris = np.genfromtxt(url, delimiter=',', dtype='object')
species = np.array([row.tolist()[4] for row in iris])
print(species)
u, counts = np.unique(species, return_counts=True)
print(u, counts)

25、如何将数字转换为分类(文本)数组?

# 将iris_2d的花瓣长度(第3列)加入以形成文本数组
# Less than 3 --> 'small'
# 3-5 --> 'medium'
# '>=5 --> 'large'
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris = np.genfromtxt(url, delimiter=',', dtype='object')
# [0, 3, 5, 10]表示划分成[0,3), [3,5), [5,10), [10,>10) 4个区间;
# 返回的petallength数组是每个元素对应这4个区间的索引
petallength = np.digitize(iris[:, 2].astype('float'), [0, 3, 5, 10])
# print(petallength)
label_map = {1: 'small', 2: 'medium', 3: 'large', 4: np.nan}
petallength2 = [label_map[x] for x in petallength]
print(petallength2)

26、如何按列对2D数组进行排序

# 根据sepallength列对数据集进行排序
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris = np.genfromtxt(url, delimiter=',', dtype='object')
print(iris[iris[:, 0].argsort()])

27、如何在numpy数组中找到最常见的值?

# 在鸢尾属植物数据集中找到最常见的花瓣长度petallenth值(第3列)
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris = np.genfromtxt(url, delimiter=',', dtype='object')
vals, counts = np.unique(iris[:, 2], return_counts=True)
# print(np.argmax(counts))  # 返回的是最大值所在的下标;
print(vals[np.argmax(counts)])

28、如何找到第一次出现的值大于给定值的位置?

# 在数据集的第4列petalwidth中查找第一次出现的值大于1.0的位置。
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris = np.genfromtxt(url, delimiter=',', dtype='object')
print(np.argwhere(iris[:, 3].astype(float) > 1.0)[0])
# print(np.argwhere(iris[:, 3].astype(float) > 1.0))  # 返回值是一个列向量
# print(np.where(iris[:, 3].astype(float) > 1.0))  # 返回值是数组

29、如何将大于给定值的所有值替换为给定的截止值?

# 从数组a中,用30替换所有大于30的元素,用10替换所有小于10的元素。
np.set_printoptions(precision=2)
np.random.seed(100)
# 生成1-50内的随机数组,长度是20个元素
a = np.random.uniform(1,50, 20)
print(a)
# [27.63 14.64 21.8  42.39  1.23  6.96 33.87 41.47  7.7  29.18 44.67 11.25
#  10.08  6.31 11.77 48.95 40.77  9.43 41.   14.43]

# Solution 1: Using np.clip
print(np.clip(a, a_min=10, a_max=30))
# [27.63 14.64 21.8  30.   10.   10.   30.   30.   10.   29.18 30.   11.25
#  10.08 10.   11.77 30.   30.   10.   30.   14.43]

# Solution 2: Using np.where
print(np.where(a < 10, 10, np.where(a > 30, 30, a)))
# [27.63 14.64 21.8  30.   10.   10.   30.   30.   10.   29.18 30.   11.25
#  10.08 10.   11.77 30.   30.   10.   30.   14.43]

30、如何从numpy数组中获取最大n值的位置?

# 获取给定数组a中前5个最大值的位置。
np.random.seed(100)
a = np.random.uniform(1,50, 20)

# 获取位置有2种方式
Solution:
print(a.argsort()[-5:])  # 默认是升序,返回的是索引数组
# [18  7  3 10 15]

# Solution 2:
print(np.argpartition(-a, 5)[:5])
# [18  7  3 10 15]

# 获取值有4种方式
# Method 1:
print(a[a.argsort()][-5:])

# Method 2:
print(np.sort(a)[-5:])

# Method 3:
print(np.partition(a, kth=-5)[-5:])

# Method 4:
print(a[np.argpartition(-a, 5)][:5])

31、 如何根据给定的分类变量创建组ID?

url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
species = np.genfromtxt(url, delimiter=',', dtype='str', usecols=[4])
np.random.seed(100)
species_small = np.sort(np.random.choice(species, size=20))

# Solution1:
# output = [np.argwhere(np.unique(species_small) == s).tolist()[0][0] for val in np.unique(species_small) for s in species_small[species_small==val]]

# Solution2: For Loop version
output = []
uniqs = np.unique(species_small)
for val in uniqs:  # uniq values in group
    for s in species_small[species_small==val]:  # each element in group
        groupid = np.argwhere(uniqs == s).tolist()[0][0]  # groupid
        output.append(groupid)
print(output)
# [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2]

32、如何在二维numpy数组的每一行中找到最大值?

# 计算给定数组中每行的最大值。
np.random.seed(100)
a = np.random.randint(1, 10, [5, 3])
print(a)
# [[9 9 4]
#  [8 8 1]
#  [5 3 6]
#  [3 3 3]
#  [2 1 9]]

# np.apply_along_axi按行或按列处理数组的函数,axis=1表示按行
# Solution 1
maxarr = np.amax(a, axis=1)
print(maxarr)
# [9 8 6 3 9]

# Solution 2
maxarr = np.apply_along_axis(np.max, arr=a, axis=1)
print(maxarr)
# [9 8 6 3 9]

33、如何在numpy数组中找到重复的记录?

# 在给定的numpy数组中找到重复的条目(第二次出现以后),并将它们标记为True。第一次出现应该是False的。
np.random.seed(100)
a = np.random.randint(0, 5, 10)
print(a)
# [0 0 3 0 2 4 2 2 2 2]
out = np.full(a.shape[0], True)
unique_positions = np.unique(a, return_index=True)[1]
print(unique_positions)  # 设置了return_index=True则返回的是下标
# [0 4 2 5] # 表示数组a中只有a[0],a[4],a[2],a[5]这四样元素
out[unique_positions] = False
print(out)
# [False  True False  True False False  True  True  True  True]

34、如何删除numpy数组中所有缺少的值?

a = np.array([1, 2, 3, np.nan, 5, 6, 7, np.nan])
a = a[~np.isnan(a)]
print(a)
# [1. 2. 3. 5. 6. 7.]

35、如何计算两个数组之间的欧氏距离?

# Input
a = np.array([1, 2, 3, 4, 5])
b = np.array([4, 5, 6, 7, 8])

# Solution
dist = np.linalg.norm(a - b)
print(dist)
# 6.708203932499369

36、如何在一维数组中找到所有的局部极大值(或峰值)?

# 找到一个一维数字数组a中的所有峰值。峰顶是两边被较小数值包围的点。
a = np.array([1, 3, 7, 1, 2, 6, 0, 1])
doublediff = np.diff(np.sign(np.diff(a)))
peak_locations = np.where(doublediff == -2)[0] + 1
print(peak_locations)
# [2 5] 返回的是极大值所在的下标

37、如何查找数组中项的第n次重复索引?

# 找出x中数字1的第5次重复的索引
x = np.array([1, 2, 1, 1, 3, 4, 3, 1, 1, 2, 1, 1, 2])
n = 5
# Solution 1:enumerate会返回一个元组数组,元组包含索引和值
# print(list(enumerate(x)))
# [(0, 1), (1, 2), (2, 1), (3, 1), (4, 3), (5, 4), (6, 3), (7, 1), (8, 1), (9, 2), (10, 1), (11, 1), (12, 2)]
index = [i for i, v in enumerate(x) if v == 1][n-1]
# Solution 2: Numpy version
index = np.where(x == 1)[0][n-1]
print(index)  # 8

38、如何在给定起始点、长度和步骤的情况下创建一个numpy数组序列?

# 创建长度为10的numpy数组,从5开始,在连续的数字之间的步长为3。
length = 10
start = 5
step = 3
def seq(start, length, step):
    end = start + (step*length)
    return np.arange(start, end, step)

print(seq(start, length, step))
# [ 5  8 11 14 17 20 23 26 29 32]

39、如何填写不规则系列的numpy日期中的缺失日期?

# 给定一系列不连续的日期序列。填写缺失的日期,使其成为连续的日期序列。
dates = np.arange(np.datetime64('2018-02-01'), np.datetime64('2018-02-25'), 2)
print(dates)
# ['2018-02-01' '2018-02-03' '2018-02-05' '2018-02-07' '2018-02-09'
#  '2018-02-11' '2018-02-13' '2018-02-15' '2018-02-17' '2018-02-19'
#  '2018-02-21' '2018-02-23']
# Solution ---------------
filled_in = np.array([np.arange(date, (date+d)) for date, d in zip(dates, np.diff(dates))]).reshape(-1)
print(filled_in)
# ['2018-02-01' '2018-02-02' '2018-02-03' '2018-02-04' '2018-02-05'
#  '2018-02-06' '2018-02-07' '2018-02-08' '2018-02-09' '2018-02-10'
#  '2018-02-11' '2018-02-12' '2018-02-13' '2018-02-14' '2018-02-15'
#  '2018-02-16' '2018-02-17' '2018-02-18' '2018-02-19' '2018-02-20'
#  '2018-02-21' '2018-02-22']

# 加上最后一天
output = np.hstack([filled_in, dates[-1]])
print(output)
# ['2018-02-01' '2018-02-02' '2018-02-03' '2018-02-04' '2018-02-05'
#  '2018-02-06' '2018-02-07' '2018-02-08' '2018-02-09' '2018-02-10'
#  '2018-02-11' '2018-02-12' '2018-02-13' '2018-02-14' '2018-02-15'
#  '2018-02-16' '2018-02-17' '2018-02-18' '2018-02-19' '2018-02-20'
#  '2018-02-21' '2018-02-22' '2018-02-23']

# # For loop version -------
# out = []
# for date, d in zip(dates, np.diff(dates)):
#     out.append(np.arange(date, (date+d)))
#
# filled_in = np.array(out).reshape(-1)
# # add the last day
# output = np.hstack([filled_in, dates[-1]])
# print(output)

40、如何从给定的一维数组创建步长?

# 从给定的一维数组arr中,生成一个二维矩阵,窗口长度为4,步距为2,类似于 [[0,1,2,3], [2,3,4,5], [4,5,6,7]..]
def gen_strides(a, stride_len=5, window_len=5):
    n_strides = ((a.size-window_len)//stride_len) + 1
    return np.array([a[s:(s+window_len)] for s in np.arange(0, n_strides*stride_len, stride_len)])

print(gen_strides(np.arange(15), stride_len=2, window_len=4))
# [[ 0  1  2  3]
#  [ 2  3  4  5]
#  [ 4  5  6  7]
#  [ 6  7  8  9]
#  [ 8  9 10 11]
#  [10 11 12 13]]

你可能感兴趣的:(python)