最近不是校招,刚好晚上睡不着,就随便整理一下numpy的东西啊,结果写嗨了。。直接写到四点,应该是把numpy讲差不多了,整体框架肯定是完整的,细节那么多,肯定不会刻意去涉及,不过核心点,大致都说了。建议小白读者跟着一块敲。 如果下载anconda,会自带numpy,如果没有的话,就直接
pip install numpy -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
numpy类似于list,但与list对象有区别
- list可以存储多种数据类型,而numpy只能同时存储一种数据类型。
- numpy可以做到线性代数中的矩阵运算,list不可以。
- numpy由c语言实现,它的速度即使经过python解释器后在某些时候都可以直接与c语言比肩。而list作为python最基本的数据结构,它本身并不高效。
import numpy as np
a = np.arange(10,20,0.1)
print(a)
np.arange(): 生成一个numpy.array对象,参数类似于python中的range迭代器。
a = np.random.random((2,3))
print(a)
a = np.random.randint(1,10,(3,3))
print(a)
[[0.70153953 0.32359607 0.94127114]
[0.2967885 0.66102347 0.37332759]]
[[2 4 8]
[8 3 9]
[5 6 4]]
np.random. 随机生成np.array对象。
a = np.zeros((2,3))
print(a)
a = np.ones((2,3))
print(a)
a = np.full((2,3), 10)
print(a)
a = np.eye(3,3)
print(a)
[[0. 0. 0.]
[0. 0. 0.]]
[[1. 1. 1.]
[1. 1. 1.]]
[[10 10 10]
[10 10 10]]
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
几个特殊函数生成几个特殊的np.array对象
np.array对象具有非常丰富的数据类型.
windows环境下,默认数据类型为np.uint32 mac与linux则需要看系统环境。
a = np.array([1,2,3])
print(a.dtype)
a = a.astype(np.int64)
print(a.dtype)
int32
int64
a = np.random.randint(0,10,(2,3))
print(a,a.dtype)
print(a.size)
print(a.ndim)
print(a.shape)
print(a.reshape(6,))
print(a.itemsize)
[[2 3 1]
[3 7 0]] int32
6
2
(2, 3)
[2 3 1 3 7 0]
4
a = np.random.randint(0,10,(2,3))
print(a)
print(a*10)
print(a/2)
print((a/3).round(2))
[[1 4 8]
[8 1 6]]
[[10 40 80]
[80 10 60]]
[[0.5 2. 4. ]
[4. 0.5 3. ]]
[[0.33 1.33 2.67]
[2.67 0.33 2. ]]
维度转换的两种方法
reshape与resize
a = np.random.randint(0,10,(2,3))
print(a)
a_1 = a.reshape(6,)
print(a)
print(a_1)
a.resize(6,)
print(a)
[[8 8 1]
[2 7 2]]
[[8 8 1]
[2 7 2]]
[8 8 1 2 7 2]
[8 8 1 2 7 2]
a = np.random.randint(0,10,(2,3))
print(a)
b = a.flatten()
b[1] = 3
print(a)
[[4 1 0]
[4 3 8]]
[[4 1 0]
[4 3 8]]
a = np.random.randint(0,10,(2,3))
print(a)
b = a.ravel()
b[1] = 3
print(a)
[[1 0 9]
[7 7 7]]
[[1 3 9]
[7 7 7]]
a1 = np.random.randint(0,10,size=(3,5))
a2 = np.random.randint(0,10,size=(1,5))
a3 = np.vstack([a1,a2])
print(a3)
[[6 4 9 8 2]
[6 3 0 3 0]
[2 0 7 9 6]
[2 8 1 3 0]]
a1 = np.random.randint(0,10,size=(3,2))
a2 = np.random.randint(0,10,size=(3,1))
a3 = np.hstack([a1,a2])
print(a3)
[[1 3 1]
[4 2 4]
[8 2 6]]
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
c = np.concatenate((a, b), axis=0)
print(c)
[[1 2]
[3 4]
[5 6]]
a = np.arange(16.0).reshape(4, 4)
print(a)
b,c = np.hsplit(a,2)
print(b)
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]]
[[ 0. 1.]
[ 4. 5.]
[ 8. 9.]
[12. 13.]]
a = np.arange(16.0).reshape(4, 4)
print(a)
b,c,d = np.hsplit(a,np.array([1,2]))
print(b)
print(c)
print(d)
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]]
[[ 0.]
[ 4.]
[ 8.]
[12.]]
[[ 1.]
[ 5.]
[ 9.]
[13.]]
[[ 2. 3.]
[ 6. 7.]
[10. 11.]
[14. 15.]]
做个小测试对比一下list与np.array的速度。
- 构建一个很大的数组。
- 构建一个计算函数时间的函数。
2.1 time库 2.2 函数装饰器 - 将两种分割方法封装到函数中。
3.1 传入可控默认参数 - 计算同样条件下的时间差,并可视化(绘图)
3.2 利用matplotlib
def func_time(func):
from time import time
def init_func(*args,**kwargs):
start = time()
func_return = func(*args,**kwargs)
end = time()
return func_return, end-start
return init_func
def get_num(n=10000):
re_num = np.arange(n)
return re_num
@func_time
def h_split_list(data,n = 5000):
np.hsplit(data,[i for i in range(n)])
return None
@func_time
def h_split_np(data,n = 5000):
np.hsplit(data,np.arange(0,n,1))
return None
from tqdm import tqdm
data = get_num(1000000)
time_np = np.zeros((10000,2)).astype(np.float64)
for i in tqdm(range(50000,60000)):
time_l = h_split_list(data, i)[1]
time_n = h_split_np(data, i)[1]
time_np[i-50000] = np.array([time_l, time_n])
100%|████████████████████████████████████████████████████████████████████████████| 10000/10000 [25:28<00:00, 6.54it/s]
array([[0.07489157, 0.08552456],
[0.07862067, 0.08474588],
[0.08583903, 0.07922769],
[0.07734418, 0.08843541],
[0.0754838 , 0.09528446],
[0.08944893, 0.07870269],
[0.08104563, 0.08205676],
[0.08094621, 0.08138871],
[0.08068252, 0.07709312],
[0.07414293, 0.0772562 ]])
print(['第'+str(i+1)+'次' for i in range(0,10000,1000)])
['第1次', '第1001次', '第2001次', '第3001次', '第4001次', '第5001次', '第6001次', '第7001次', '第8001次', '第9001次']
len(time_np)
10000
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
plt.rcParams['figure.figsize'] = (16.0, 8.0)
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'
res_1 = plt.bar([i for i in range(10)],np.hsplit(time_np[0:10000:1000], 2)[0].flatten().round(2),width=0.4, label="迭代式")
res_2 = plt.bar([i+0.4 for i in range(10)],np.hsplit(time_np[0:10000:1000], 2)[1].flatten().round(2),width=0.4, label='np.array')
plt.ylim(0, 0.15)
plt.xticks([i + 0.2 for i in range(10)], ['第{}次'.format(i) for i in range(10)])
plt.legend(fontsize=20)
for rect in res_1:
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / 2, height+0.001, str(height), ha="center", va="bottom")
for rect in res_2:
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / 2, height+0.001, str(height), ha="center", va="bottom")
plt.show()

a = np.arange(16.0).reshape(4, 4)
b = a
print(b)
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]]
a = np.arange(16.0).reshape(4, 4)
b = a.view()
print(b)
b[0][0] = 1
print(a)
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]]
[[ 1. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]]
a = np.arange(16.0).reshape(4, 4)
print(a)
b = a.copy()
b[0][0] = 5
print(a)
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]]
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]]
现在再来分析之前flatten和ravel它们的区别就在于浅拷贝和深拷贝。ravel()方法就是视图操作,而flatten就是深拷贝操作。
numpy中有一种独特的存储np.array对象的文件类型。如下:
fname = 'test_np.npy'
a = np.arange(16.0).reshape(4, 4)
np.save(fname,a)
data = np.load(fname)
print(data)
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]]
这种结构的出现无疑是加快了numpy对于文件操作的速度。
csv文件处理
import csv
with open('stock.csv','r',newline='') as fp:
reader = csv.reader(fp)
header = next(reader)
print(header)
for line in reader:
continue
['index', 'secID', 'ticker', 'secShortName', 'exchangeCD', 'tradeDate', 'preClosePrice', 'openPrice', 'highestPrice', 'lowestPrice', 'closePrice', 'turnoverVol']
观察可知,csv读取后,每一行得到的值是一个列表,之前就已经说过,这并不高效,因此其实对于更大的数据,应该是采用pandas处理的,不过csv也是必修。列表中显然都是字符串数据,其实csv也是纯文本文件,所以才会这样。
header = ['id','name']
with open('test_1.csv','w',newline='',encoding='utf-8') as fp:
values = [
('1','张三'),
('2','李四'),
]
writer = csv.writer(fp)
writer.writerow(header)
writer.writerows(values)

header = ['id','name']
with open('test_2.csv','w',newline='',encoding='utf-8') as fp:
values = {'id':'1', 'name':'张三'}
writer = csv.DictWriter(fp,header)
writer.writeheader()
writer.writerow(values)

特殊值的处理
if np.NAN != np.NAN :
print('测试')
测试
data = np.random.randint(0,10,size=(3,5)).astype(np.float64)
data[0,1] = np.nan
print(data)
data = data[~np.isnan(data)]
print(data)
[[ 6. nan 9. 6. 7.]
[ 1. 3. 1. 9. 2.]
[ 3. 7. 2. 1. 5.]]
[6. 9. 6. 7. 1. 3. 1. 9. 2. 3. 7. 2. 1. 5.]
data = np.random.randint(0,10,size=(3,5)).astype(np.float64)
data[[0,1],[1,2]] = np.NAN
print(data)
lines = np.where(np.isnan(data))[0]
data1 = np.delete(data,lines,axis=0)
print(data1)
[[ 2. nan 7. 9. 1.]
[ 4. 8. nan 1. 3.]
[ 2. 3. 0. 4. 6.]]
[[2. 3. 0. 4. 6.]]
最好的方法是利用其他值进行替代,例如提取列均值或者行均值填充。
scores = np.loadtxt("nan_scores.csv",skiprows=1,delimiter=",",encoding="utf-8",dtype=np.str_)
scores[scores == ""] = np.NAN
print(scores)
scores = scores.astype(np.float64)
scores1=scores.copy()
scores2 = scores.copy()
for x in range(scores2.shape[1]):
score = scores2[:,x]
non_nan_score = score[score == score]
score[score != score] = non_nan_score.mean()
print(scores2.mean(axis=0))
[['59' '89']
['90' '32']
['78' '45.5']
['34' 'nan']
['nan' '56']
['23' '56']]
[56.8 55.7]
如上就是利用np.array对象和逻辑对NAN值进行了一个巧妙的处理并计算了他们的均值。
print(type(np.NAN))
print(type(np.Inf))
<class 'float'>
<class 'float'>
random模块
random模块随机库,不论是python还是numpy都是必修,方法必须掌握,它甚至在后期的机器学习中都非常重要。 这里有一点属于常识,不论是什么random,java也好,c++也好,python也好,他们的随机都是伪随机,并非我们在日常生活中蒙着眼睛去蒙那样的真随机。 这点由计算机决定,没有办法改变,至少目前是没有什么办法做到真随机。不过有一个特别有意思呀,就是,咱不都说什么遇事不决,量子力学,还真可以 真随机可以在量子世界中产生,为啥呢,因为理论上量子世界中有些东西在原则是无法预测的,而我们的计算机产生随机数的原理,就是通过一个数字进行 一系列的运算,这就很有意思呀,因为只要是一样的数据,经过成千上万次运算他也还是那样,所以只能通过不断改变引入的这个数字,但是改变的过程也 是可计算的呀,所以目前的计算机做不到真随机啊。
np.random.seed(1)
print(np.random.rand())
print(np.random.rand())
0.417022004702574
0.7203244934421581
print(np.random.rand(1,2))
print(np.random.rand(2,2))
[[0.14675589 0.09233859]]
[[0.18626021 0.34556073]
[0.39676747 0.53881673]]
import math
import numpy as np
import matplotlib.pyplot as plt
u = 0
sig = math.sqrt(1)
x = np.linspace(u - 3*sig, u + 3*sig, 50)
y = np.exp(-(x - u) ** 2 / (2 * sig ** 2)) / (math.sqrt(2*math.pi)*sig)
plt.plot(x, y, "b", linewidth=2)
plt.grid(True)
plt.show()

data1 = np.random.randint(10,size=(3,5))
print(data1)
[[5 2 4 2 4]
[7 7 9 1 7]
[0 6 9 9 7]]
data = [4,65,6,3,5,73,23,5,6]
result1 = np.random.choice(data,size=(2,3))
print(result1)
result2 = np.random.choice(data,3)
print(result2)
result3 = np.random.choice(10,3)
print(result3)
[[65 3 5]
[ 6 65 5]]
[4 3 6]
[0 4 9]
a = np.arange(10)
print(a)
np.random.shuffle(a)
print(a)
[0 1 2 3 4 5 6 7 8 9]
[6 0 2 8 1 3 4 5 9 7]
以上演示的其实都是很重要的呀,但它不代表其他不重要,总之能记还是尽量多记一些呀,都是码农嘛,记得越多越好。

可能有人会问正态分布到底是个啥哈。。。这个。。就不解释了,直接上个公式吧,一个密度函数,一个分布函数,推导过程写到这,大家自己把。如下图: 
知己难寻,笑苍天无眼
|