Numpy基础(一)

Numpy是Python一个很重要的第三方库,用于科学计算。
注:以下代码均在jupyter qtconsole中实现,导入了%pylab环境。


生成数据

linspace

linspace用来生成一组等间隔的数据

In [51]: %pylab # 启用pylab模式,直接导入了很多科学计算库。
In [52]: a = linspace(0, 2*pi, 21)

In [53]: a
Out[53]: 
array([ 0.        ,  0.31415927,  0.62831853,  0.9424778 ,  1.25663706,
        1.57079633,  1.88495559,  2.19911486,  2.51327412,  2.82743339,
        3.14159265,  3.45575192,  3.76991118,  4.08407045,  4.39822972,
        4.71238898,  5.02654825,  5.34070751,  5.65486678,  5.96902604,
        6.28318531])

In [54]: %precision 3 # 在qtconsole中设置数据显示精度为小数点后3位。若直接使用%precision即可恢复默认精度。
Out[54]: '%.3f'

In [55]: a
Out[55]: 
array([ 0.   ,  0.314,  0.628,  0.942,  1.257,  1.571,  1.885,  2.199,
        2.513,  2.827,  3.142,  3.456,  3.77 ,  4.084,  4.398,  4.712,
        5.027,  5.341,  5.655,  5.969,  6.283])

ogrid

ogrid方法产生一系列等差数据,类似于Matlabstart:step:stop。示例如下:

In [27]: x = ogrid[0:10]

In [28]: x
Out[28]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [29]: x = ogrid[0:10:2]

In [30]: x
Out[30]: array([0, 2, 4, 6, 8])

# 小技巧:若产生的数组要包含末尾的数,可以使用虚数符号"j"加以实现。
In [32]: x
Out[32]: array([  0.,   1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.])

In [33]: x = ogrid[0:10:6j]

In [34]: x
Out[34]: array([  0.,   2.,   4.,   6.,   8.,  10.])

# 还可以直接产生二维数据
In [35]: x, y = ogrid[0:10:2, 10:20:6j]

In [36]: x
Out[36]: 
array([[ 0.],
       [ 2.],
       [ 4.],
       [ 6.],
       [ 8.]])

In [37]: y
Out[37]: array([[ 10.,  12.,  14.,  16.,  18.,  20.]])

另外,r_c_分别产生行向量数据与列向量数据,使用方法与此类似。

快捷方式产生矩阵

oneszerosemptyidentity等分别产生1矩阵,0矩阵,空矩阵(0矩阵),单位矩阵(对角线为1)

显示命名空间参数

使用who()或者whos即可显示当前命名空间参数,如:

In [92]: who()
Name            Shape            Bytes            Type
===========================================================

size            200              1600             float64
a               21               168              float64
b               21               168              float64
_25 (b)         21               168              float64
_29 (b)         21               168              float64
_30             21               21               bool
x               50               400              float64
_45             200              1600             float64
y               50               400              float64
_48             200              1600             float64
_50 (_45)       200              1600             float64
_51 (_48)       200              1600             float64
_53 (size)      200              1600             float64
color           200              1600             float64
t               50               400              float64

Upper bound on total bytes  =       7957

In [93]: whos
Variable   Type       Data/Info
-------------------------------
a          ndarray    21: 21 elems, type `float64`, 168 bytes
b          ndarray    21: 21 elems, type `float64`, 168 bytes
color      ndarray    200: 200 elems, type `float64`, 1600 bytes
size       ndarray    200: 200 elems, type `float64`, 1600 bytes
t          ndarray    50: 50 elems, type `float64`, 400 bytes
x          ndarray    50: 50 elems, type `float64`, 400 bytes
y          ndarray    50: 50 elems, type `float64`, 400 bytes

数组属性

建立了数组a,则它的常用属性如下:

In [162]: a = array([[1, 2, 3], [4, 5, 6]])

In [163]: a
Out[163]: 
array([[1, 2, 3],
       [4, 5, 6]])

1.查看类型

In [164]: type(a)
Out[164]: numpy.ndarray

2.查看数组中的数据类型

In [165]: a.dtype
Out[165]: dtype('int64')

3.查看数组中每个元素所占字节

In [166]: a.itemsize
Out[166]: 8

4.查看数组的行列数

In [167]: a.shape
Out[167]: (2, 3) # 说明是2行3列的数组

5.查看数组元素数目

In [168]: a.size
Out[168]: 6 # 数组元素数目等于行数与列数的乘积

6.查看数组所占空间

In [169]: a.nbytes
Out[169]: 48 # 数组所占空间为数组的itemize与size的乘积

7.查看数组维数

In [170]: a.ndim
Out[170]: 2 # 表明是二维数组

fill填充数据

fill方法将数组设置为指定值。如:

In [180]: a
Out[180]: 
array([[1, 2, 3],
       [4, 5, 6]])

In [181]: a.fill(-4.8)

In [182]: a
Out[182]: 
array([[-4, -4, -4],
       [-4, -4, -4]])

注意,此时a保持行列数不变,元素全部变成了-4。但是为什么不是-4.8呢?那是因为此时数组adtypeint,所以只能保留为整数。可做如下更改:

In [183]: a.dtype
Out[183]: dtype('int64')

In [184]: a.dtype = 'float'

In [185]: a.dtype
Out[185]: dtype('float64')

In [186]: a.fill(-4.8)

In [187]: a
Out[187]: 
array([[-4.8, -4.8, -4.8],
       [-4.8, -4.8, -4.8]])

可以看到,此时a中所有元素变成了-4.8

任意类型的数组

numpy中的数组默认为同一类型,可以是数值型,也可以是字符串型,但不能是混合型。但是,当使用dtype=object时,即可创建任意类型的数组。如:

In [398]: a = array([1, 1.2, 'hello', [10, 20, 30]], dtype=object)

In [399]: a
Out[399]: array([1, 1.2, 'hello', [10, 20, 30]], dtype=object)

In [400]: a.itemsize
Out[400]: 8

In [402]: a.dtype
Out[402]: dtype('O')

In [403]: a * 2
Out[403]: array([2, 2.4, 'hellohello', [10, 20, 30, 10, 20, 30]], dtype=object)

数据引用

切片引用

现有原数组a,切片引用产生了数组b,修改b中的元素会影响a中的元素。如:

In [248]: a = array([0, 1, 2, 3, 4])

In [249]: a
Out[249]: array([0, 1, 2, 3, 4])

In [252]: b = a[2:4]

In [253]: b
Out[253]: array([2, 3])

In [254]: b[0] = 999

In [255]: b
Out[255]: array([999,   3])

In [256]: a
Out[256]: array([  0,   1, 999,   3,   4])

说明在numpy数组中,python并没有为b分配新的内存空间,而是让b指向了a分配的内存空间。因此,改变b会改变a的值。
python默认的列表就不存在此现象,如:

In [257]: a = [0, 1, 2, 3, 4]

In [258]: b = a[2:4]

In [259]: b
Out[259]: [2, 3]

In [260]: b[0] = 999

In [261]: b
Out[261]: [999, 3]

In [262]: a
Out[262]: [0, 1, 2, 3, 4]

若要在numpy的数组中,改变b不影响a的值,可以使用copy()实现,如:

In [271]: a = array([0, 1, 2, 3, 4])

In [272]: b = a[2:4].copy()

In [275]: b[0] = 999

In [276]: b
Out[276]: array([999,   3])

In [277]: a
Out[277]: array([0, 1, 2, 3, 4])

数组方法

sum求和

In [8]: a
Out[8]: 
array([[1, 2, 3],
       [4, 5, 6]])

In [9]: sum(a)
Out[9]: 21

In [12]: a.sum()
Out[12]: 21

沿着指定维度求和

In [10]: sum(a, axis=0) # 沿着行的维度求和
Out[10]: array([5, 7, 9])

In [11]: sum(a, axis=1) # 沿着列的维度求和
Out[11]: array([ 6, 15])

In [14]: a.sum(axis=0) # 沿着第一维求和
Out[14]: array([5, 7, 9])

In [16]: a.sum(axis=1) # 沿着第二维求和
Out[16]: array([ 6, 15])

prod求积

使用方法同sum
此外,maxminmeanstdvar等方法与sum方法的使用也差不多。

clip

将数值限制在某个范围

In [66]: a
Out[66]: 
array([[1, 2, 3],
       [4, 5, 6]])

In [67]: a.clip(3, 5) # a中小于3的数变成3,大于5的数变成5
Out[67]: 
array([[3, 3, 3],
       [4, 5, 5]])

In [68]: a
Out[68]: 
array([[1, 2, 3],
       [4, 5, 6]])

ptp

计算数组中最大值与最小值的差

In [68]: a
Out[68]: 
array([[1, 2, 3],
       [4, 5, 6]])

In [69]: a.ptp()
Out[69]: 5

In [70]: a.ptp(axis=0)
Out[70]: array([3, 3, 3])

In [71]: a.ptp(axis=1)
Out[71]: array([2, 2])

round

四舍五入,0.5的近似规则为近似到偶数值。

In [78]: b = rand(10)*10

In [79]: b
Out[79]: 
array([ 2.57598829,  7.69588774,  9.79707955,  7.10994638,  5.27285863,
        6.50838994,  9.39987486,  4.00583049,  2.58985365,  5.69761458])

In [80]: b.round()
Out[80]: array([  3.,   8.,  10.,   7.,   5.,   7.,   9.,   4.,   3.,   6.])

In [81]: b.round(decimals=1) # 保留1位小数的近似
Out[81]: array([ 2.6,  7.7,  9.8,  7.1,  5.3,  6.5,  9.4,  4. ,  2.6,  5.7])

从一列数据中抽出某个区间的数据

假设有0到100之间的100个随机数,如何找出40到60之间的数据?

In [163]: a = floor(rand(100) * 100)

In [164]: a
Out[164]: 
array([  4.,  10.,   6.,  33.,  77.,  43.,  19.,  74.,  43.,  24.,  70.,
        97.,  25.,  55.,   2.,  26.,  21.,  79.,  71.,  66.,   9.,   2.,
        75.,  96.,  27.,  32.,   0.,   6.,   3.,  24.,  92.,  24.,  94.,
        38.,  34.,  67.,  81.,  94.,  55.,  16.,  22.,  88.,  76.,  53.,
        30.,  35.,  13.,   7.,  70.,  63.,  25.,  29.,  91.,  62.,  57.,
        86.,  77.,  41.,  68.,  52.,   1.,  18.,  94.,  20.,  60.,  86.,
        80.,  57.,  13.,  87.,   8.,  12.,  86.,  75.,   6.,  54.,  84.,
        36.,  34.,  56.,  37.,  55.,  85.,  22.,  18.,  95.,   8.,  91.,
        50.,  25.,  94.,  60.,  20.,  18.,  49.,  18.,  37.,  97.,  33.,
        67.])

方法之一是使用searchsorted函数实现。searchsorted有两个参数,第一个参数是一列一维数组,第二个参数是一系列值,返回值相当于保持第一个数组的排序性质不变,将第二个数组中的值插入第一个数组中的位置。看示例:

In [183]: a.sort() # 对a进行从小到大排序

In [184]: a
Out[184]: 
array([  0.,   1.,   2.,   2.,   3.,   4.,   6.,   6.,   6.,   7.,   8.,
         8.,   9.,  10.,  12.,  13.,  13.,  16.,  18.,  18.,  18.,  18.,
        19.,  20.,  20.,  21.,  22.,  22.,  24.,  24.,  24.,  25.,  25.,
        25.,  26.,  27.,  29.,  30.,  32.,  33.,  33.,  34.,  34.,  35.,
        36.,  37.,  37.,  38.,  41.,  43.,  43.,  49.,  50.,  52.,  53.,
        54.,  55.,  55.,  55.,  56.,  57.,  57.,  60.,  60.,  62.,  63.,
        66.,  67.,  67.,  68.,  70.,  70.,  71.,  74.,  75.,  75.,  76.,
        77.,  77.,  79.,  80.,  81.,  84.,  85.,  86.,  86.,  86.,  87.,
        88.,  91.,  91.,  92.,  94.,  94.,  94.,  94.,  95.,  96.,  97.,
        97.])

In [185]: bounds = 40, 60 # 设定边界,下边界为40,上边界为60

In [186]: low_idx, high_idx = searchsorted(a, bounds) #使用searchsorted函数

In [187]: low_idx # 获取a中下边界40对应的数组下标
Out[187]: 48

In [188]: high_idx # 获取a中上边界60对应的数组下标
Out[188]: 62

In [189]: a[low_idx]
Out[189]: 41.0

In [190]: a[high_idx]
Out[190]: 60.0

In [191]: a[low_idx:high_idx] # 取得a中40到60之间的数
Out[191]: 
array([ 41.,  43.,  43.,  49.,  50.,  52.,  53.,  54.,  55.,  55.,  55.,
        56.,  57.,  57.])

连接数组

使用concatenatevstackhstack等方法。

In [2]: x = array([[0, 1, 2], [10, 11, 12]])

In [3]: y = array([[50, 51, 52], [60, 61, 62]])

In [4]: z = concatenate((x, y)) # 沿着第一维度进行连接

In [5]: z
Out[5]: 
array([[ 0,  1,  2],
       [10, 11, 12],
       [50, 51, 52],
       [60, 61, 62]])

In [6]: vstack((x, y))
Out[6]: 
array([[ 0,  1,  2],
       [10, 11, 12],
       [50, 51, 52],
       [60, 61, 62]])

In [7]: concatenate((x, y), axis=1) # 沿着第二维度进行连接
Out[7]: 
array([[ 0,  1,  2, 50, 51, 52],
       [10, 11, 12, 60, 61, 62]])

In [8]: hstack((x, y))
Out[8]: 
array([[ 0,  1,  2, 50, 51, 52],
       [10, 11, 12, 60, 61, 62]])

扁平化数组

flattenflat,方法将多维数组降为1维

In [10]: z
Out[10]: 
array([[ 0,  1,  2],
       [10, 11, 12],
       [50, 51, 52],
       [60, 61, 62]])

In [12]: z.flatten()
Out[12]: array([ 0,  1,  2, 10, 11, 12, 50, 51, 52, 60, 61, 62])

In [20]: z # 说明flatten()不影响原数组
Out[20]: 
array([[ 0,  1,  2],
       [10, 11, 12],
       [50, 51, 52],
       [60, 61, 62]])

In [22]: z.flat[:] # 使用flat方法也能实现
Out[22]: array([ 0,  1,  2, 10, 11, 12, 50, 51, 52, 60, 61, 62])

In [23]: z.flat # 此时返回一个迭代器
Out[23]: <numpy.flatiter at 0x7fa602180a00>

In [24]: list(z.flat)
Out[24]: [0, 1, 2, 10, 11, 12, 50, 51, 52, 60, 61, 62]

In [25]: z.ravel()
Out[25]: array([ 0,  1,  2, 10, 11, 12, 50, 51, 52, 60, 61, 62])

In [26]: z # ravel方法不影响原数组
Out[26]: 
array([[ 0,  1,  2],
       [10, 11, 12],
       [50, 51, 52],
       [60, 61, 62]])

astype

astype实现数据类型转换

In [77]: a = ones([5, 4])

In [78]: a
Out[78]: 
array([[ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.]])

In [79]: a.astype(int)
Out[79]: 
array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1]])

In [80]: a
Out[80]: 
array([[ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.]])

In [81]: a.dtype
Out[81]: dtype('float64')

# 不能直接改变dtype进行类型转换
In [82]: a.dtype = 'int'

In [83]: a
Out[83]: 
array([[4607182418800017408, 4607182418800017408, 4607182418800017408,
        4607182418800017408],
       [4607182418800017408, 4607182418800017408, 4607182418800017408,
        4607182418800017408],
       [4607182418800017408, 4607182418800017408, 4607182418800017408,
        4607182418800017408],
       [4607182418800017408, 4607182418800017408, 4607182418800017408,
        4607182418800017408],
       [4607182418800017408, 4607182418800017408, 4607182418800017408,
        4607182418800017408]])
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容