原文链接: https://www.machinelearningplus.com/python/numpy-tutorial-python-part2/
1、数组的连接
# 1、连接数组操作;
# 方法1:通过将axis参数更改为0垂直和1水平 np.concatenate
# 方法2:和np.vstack垂直和np.hstack水平
# 方法3:和np.r_垂直和np.c_水平
# 推荐使用np.vstack([a, b])垂直叠加;np.hstack([a, b])水平连接
# 1.1连接一维数组;
a = np.arange(0, 5)
b = np.arange(5, 10)
print(np.vstack([a, b]))
# [[0 1 2 3 4]
# [5 6 7 8 9]]
print(np.hstack([a, b]))
# [0 1 2 3 4 5 6 7 8 9]
# 1.2、连接二维数组
a = np.zeros([4, 4])
b = np.ones([4, 4])
print(np.vstack([a, b]))
# [[0. 0. 0. 0.]
# [0. 0. 0. 0.]
# [0. 0. 0. 0.]
# [0. 0. 0. 0.]
# [1. 1. 1. 1.]
# [1. 1. 1. 1.]
# [1. 1. 1. 1.]
# [1. 1. 1. 1.]]
print(np.hstack([a, b]))
# [[0. 0. 0. 0. 1. 1. 1. 1.]
# [0. 0. 0. 0. 1. 1. 1. 1.]
# [0. 0. 0. 0. 1. 1. 1. 1.]
# [0. 0. 0. 0. 1. 1. 1. 1.]]
2、数组的排序
# 2、数组的排序
np.random.seed(100)
arr = np.random.randint(1, 6, size=[8, 4])
print(arr)
# [[1 1 4 1]
# [3 5 3 3]
# [3 3 2 1]
# [1 5 4 5]
# [3 1 4 2]
# [3 4 5 5]
# [2 4 5 5]
# [4 4 4 2]]
# 2.1一个有缺陷的方法,np.sort(arr, axis=0),axis=0表示对每一列升序排序,默认也是axis=0;
# axis=1是对每一行进行升序排序
# 缺陷在于,该方法会对所有列进行排序,彼此独立,导致结果会损害行项的完整性
arr_sort = np.sort(arr, axis=0)
print(arr_sort)
# [[1 1 2 1]
# [1 1 3 1]
# [2 3 4 2]
# [3 4 4 2]
# [3 4 4 3]
# [3 4 4 5]
# [3 5 5 5]
# [4 5 5 5]]
# 2.2我们希望按照某一列对整个数组排序,使用np.argsort(arr),该方法返回排序好的索引数组
# 根据arr的第一列对整个数组排序,返回索引;也可以写成arr[:, 0].argsort()
arr_argsort = np.argsort(arr[:, 0])
print(arr_argsort)
# 注意,打印的是排序好的索引数组
# [0 3 6 1 2 4 5 7]
print(arr[arr_argsort])
# 打印排序好的数组
# [[1 1 4 1]
# [1 5 4 5]
# [2 4 5 5]
# [3 5 3 3]
# [3 3 2 1]
# [3 1 4 2]
# [3 4 5 5]
# [4 4 4 2]]
# 当我们要获取降序排列的数组,可以对升序的索引进行反转
# print(arr[arr_argsort[::-1]])
# 2.3根据2列或更多列对数组进行排序,使用np.lexsort()
# 如下,是在第0列排序好的基础上,再对第1列排序;即会先对元组最右侧指定的列进行排序
arr_lexsort = np.lexsort((arr[:, 1], arr[:, 0]))
print(arr_lexsort)
# 返回的是最终排序好的第0列索引
# [0 3 6 4 2 5 1 7]
print(arr[arr_lexsort])
# [[1 1 4 1]
# [1 5 4 5]
# [2 4 5 5]
# [3 1 4 2]
# [3 3 2 1]
# [3 4 5 5]
# [3 5 3 3]
# [4 4 4 2]]
3、datetime64对象
# 3、Numpy中的时间对象datetime64
# 3.1将字符串转化成datetime64对象
date_dt64 = np.datetime64('2018-02-04 23:10:10')
print(date_dt64)
# 2018-02-04T23:10:10
# 将时间对象转化成字符串
strdate_dt64 = np.datetime_as_string(date_dt64)
print(strdate_dt64)
# 2018-02-04T23:10:10
# 3.2 对datetime64对象的操作
# 删除时间组件
date = np.datetime64(date_dt64, 'D')
print(date)
# 2018-02-04
# 添加单位
m = np.timedelta64(10, 'm')
s = np.timedelta64(10, 's')
ns = np.timedelta64(10, 'ns')
print(m)
print(s)
print(ns)
# 10 minutes
# 10 seconds
# 10 nanoseconds
# 时间的增加
print(date + 10)
print(date + m)
print(date + s)
print(date + ns)
# 2018-02-14
# 2018-02-04T00:10
# 2018-02-04T00:00:10
# 2018-02-04T00:00:00.000000010
# 3.3 工作日的处理
# 过滤工作日
print(np.is_busday(date)) # False
# 增加2个工作日,滚动到最近的工作日
print(np.busday_offset(date, 2, roll='forward')) # 2018-02-07
# 增加2个工作日,向后滚动至最近的工作日
print(np.busday_offset(date, 2, roll='backward')) # 2018-02-06
# 创建日期序列
dates = np.arange(np.datetime64('2018-02-01'), np.datetime64('2018-02-10'))
print(dates)
# ['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']
print(np.is_busday(dates))
# [ True True False False True True True True True]
# 3.4 将numpy.datetime64转换为datetime.datetime对象,方式1
date_dt = date_dt64.tolist()
print(type(date_dt), date_dt)
# 2018-02-04 23:10:10
# 将numpy.datetime64转换为datetime.datetime对象,方式2
from datetime import datetime
date_dt = date_dt64.astype(datetime)
4、vectorize - 使标量函数适用于向量
# 函数foo(见下面的代码)接受一个数字,如果它是'奇数'则将其平方,否则它将它除以2
# 在标量(单个数字)上应用此函数时,它可以正常工作,但在应用于数组时会失败
# 使用numpy.vectorize() ,你可以神奇地使它在数组上工作。
def foo(x):
if x % 2 == 1:
return x**2
else:
return x/2
print(foo(10)) # 5.0
print(foo(11)) # 121
# print(foo([10, 11, 12])) # Error
# 对标量函数进行矢量化,以便标量函数可以在数组上运行; otypes提供输出的数据类型
foo_v = np.vectorize(foo, otypes=[float])
print(foo_v([10, 11, 12]))
# [ 5. 121. 6.]
print(foo_v([[10, 11, 12], [1, 2, 3]]))
# [[ 5. 121. 6.]
# [ 1. 1. 9.]]
5、np.apply_along_axis按列或行应用函数
# 按列或行应用函数;numpy.apply_along_axis
np.random.seed(100)
arr_x = np.random.randint(1, 10, size=[4, 10])
print(arr_x)
# [[9 9 4 8 8 1 5 3 6 3]
# [3 3 2 1 9 5 1 7 3 5]
# [2 6 4 5 5 4 8 2 2 8]
# [8 1 3 4 3 6 9 2 1 8]]
#
# # 如何找到每一行或每一列中最大值和最小值的差值?
def max_minus_min(x):
return np.max(x) - np.min(x)
#
# 参数1表示max_minus_min函数应用于数组arr_x的行
print(np.apply_along_axis(max_minus_min, 1, arr=arr_x))
# [8 8 6 8]
# 参数0表示max_minus_min函数应用于数组arr_x的列
print(np.apply_along_axis(max_minus_min, 0, arr=arr_x))
# [7 8 2 7 6 5 8 5 5 5]
6、其他函数
# 6.1 searchsorted - 找到要插入的位置,以便数组保持排序状态
x = np.arange(10)
# 打印5应该插入到哪个位置;默认side是left,即会插在相同元素的左边
print(np.searchsorted(x, 5)) # 5
print(np.searchsorted(x, 5, side='right')) # 6
# 6.2 np.newaxis将一维数组转化为二维数组/列向量
x = np.arange(5)
x_col = x[:, np.newaxis]
print(x_col)
# [[0]
# [1]
# [2]
# [3]
# [4]]
# 6.3 np.digitize(arr, bins)返回每个元素所属的bin的索引位置
x = np.arange(10)
bins = np.array([0, 1, 4, 9])
print(np.digitize(x, bins))
# bins划分了4个区间,[0,1) [1,4) [4,9) [9,+),如下返回的就是数组x中的每个元素对应的区间索引,从1开始
# [1 2 2 2 3 3 3 3 3 4]