數據分析(二)--numpy

numpy

numpy的主要對象是同種元素的多維數組。

numpy底層是用C語言實現的。

面試

數組和列表有什麼區別?

結構同樣都是[元素1,元素2,元素3 … ]。

在C語言、java中叫做數組;在python中叫做列表。

python中的列表可以存儲不同類型的對象;C語言中的數組只能存放相同類型的數據。

導包

import numpy as np

一、numpy介紹

numpy是用於數據科學計算的基礎,不但能夠完成科學計算任務,還能被用作高效地多維數據容器。用於存儲和處理大型矩陣。

python提供了一個 array 模塊,和 list 不同,它直接保存數值,但是python的 array模塊不支持多維,也沒有各種運算函數。

numpy彌補了這一遺憾。numpy 提供了一種存儲單一數據類型的多維數組–ndarray。

軸(axes)–維度

秩(rank)–軸的個數

(一)array創建數組

1.一維數組

arr1 = np.array([1,2,3])
print('arr1的維度:',arr1.shape)    #(3,)
print('arr1的秩:',arr1.ndim)    # 1

2.二維數組

arr2 = np.array([[1],[2],[3]])
print('arr2的維度:',arr2.shape)    # (3, 1)
print('arr2的秩:',arr2.ndim)    # 2

結論

一位數組的秩爲1,二維數組的秩爲2

即arr.ndim = len(arr.shape)

(二)常用屬性

1.秩:ndim

2.維度:shape

arr3 = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(arr3.shape)
print(arr3.ndim)
print(len(arr3.shape))

3.數組元素的總個數size

print(arr3.size)

4.數組元素的類型dtype

print(arr3.dtype)    # int32
arr4 = np.array([0.1,0.2,0.3])
print(arr4.dtype)    # float64

5.每個元素的字節大小itemsize

一個字節(byte)=8 位(bit)

print(arr3.itemsize)    # 4
print(arr4.itemsize)    # 8

6.緩衝區:data

arr5 = np.array([1,2,3])
print(arr5.dtype)
print(arr5.itemsize)
print(arr5.data)    # <memory at 0x00000000038F14C8>
print(arr5[0])

索引從0開始的原因:

arr5就是arr5.data,即存儲地址的別名

[]中的數字,表示取指定元素,需要跨進的單元

取第一個元素,不用跨進,所以爲0
在這裏插入圖片描述

(三)創建數組的方法

1.使用array()

# def array(p_object, dtype=None, copy=True, order='K', subok=False, ndmin=0):
# p_onject--接收一個array
# dtype--接受一個data-type,表示數組所需要的數據類型,如果沒有給定,則根據傳入元素的,指定隨需要的最小數據類型
arr1 = np.array([1,2,3,4])
print(arr1)
arr2 = np.array([[1,2],[3,4]])
print(arr2)
arr3 = np.array([(1,2),(3,4)])
print(arr3)
arr4 = np.array([1,2,3,4],dtype=np.float64)
print(arr4)

2.使用arange()

# def arange(start=None, stop=None, step=None, dtype=None):
# 值域[start,stop)
arr5 = np.arange(0,1,0.1)
print(arr5)

3.使用linspace()

# def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None):
# 值域[start,stop],num--元素數量
arr6 = np.linspace(0.1,1,10)
print(arr6)

4.使用logspace()–等比

# def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None):
arr7 = np.logspace(1,3,3)
print(arr7)
arr8 = np.logspace(1,10,10,base=2)
print(arr8)

5.使用zeros()–全0數組

# def zeros(shape, dtype=None, order='C')
arr9 = np.zeros((2,3))
print(arr9)

6.使用ones()–全1數組

# def ones(shape, dtype=None, order='C'):
arr10 = np.ones((2,3))
print(arr10)

7.使用empty()

創建一個內容隨機並且依賴於內存狀態的數組。

print(np.empty((2,3)))

8.使用eye()–單位數組

arr11 = np.eye(3)
print(arr11)
# [[ 1.  0.  0.]
#  [ 0.  1.  0.]
#  [ 0.  0.  1.]]
print(np.eye(2,3))
# [[ 1.  0.  0.]
#  [ 0.  1.  0.]]

9.使用diag()

arr12 = np.diag([1,2,3,4])
print(arr12)
# [[1 0 0 0]
#  [0 2 0 0]
#  [0 0 3 0]
#  [0 0 0 4]]

練習

1.生成一個3*5的數組,數組元素爲0-14之間的整數

方法1:

arr1 = np.arange(0,15)
arr1.shape = (3,5)
print(arr1)

方法2:

arr2 = np.arange(0,15).reshape(3,5)
print(arr2)

2.輸出數據的維度、秩、元素類型、元素個數

print('維度:',arr1.shape)
print('秩:',arr1.ndim)
print('元素類型:',arr1.dtype)
print('元素個數:',arr1.size)

(四)生成隨機數組

1.random.random(n)

值域[0,1),n表示生成元素的個數。

arr1 = np.random.random(3)
print(arr1)
arr2 = np.random.random(15).reshape((3,5))
print(arr2)

2.random.rand(m,n,…)

表示生成一個m*n*...的多維數組,值域爲[0,1)。

arr3 = np.random.rand(2,3)

3.random.randn(n)

生成正態隨機數,n表示生成元素的個數。

arr4 = np.random.randn(4)
print(arr4)
import matplotlib.pyplot as plt
plt.hist(arr4)
plt.show()

發現並沒有看出什麼正態分佈的趨勢。

這就涉及到了大數定理。

把n的值變爲1000試試?

arr4 = np.random.randn(1000)
import matplotlib.pyplot as plt
plt.hist(arr4)
plt.show()

這次就有正態分佈的效果了
在這裏插入圖片描述

4.random.randint(a,b,size=(m,n))

# def randint(low, high=None, size=None, dtype='l'):
# 值域[a,b],維度(m,n)的數組
arr5 = np.random.randint(1,10,size=(2,5))
print(arr5)

5.擴展:random模塊常用隨機生成函數

normal():生成正態(高斯)分佈的隨機數

# def normal(loc=0.0, scale=1.0, size=None):
# loc:float--概率分佈的均值,對應着整個分佈的中心center
# scale:float--概率分佈的標準差,對應於分佈的寬度,scale越大越矮胖,scale越小,越瘦高
# size:int or tuple of ints--輸出的shape,默認爲None,只輸出一個值

beta():生成beta分佈的隨機數

在概率論中,貝塔分佈,也稱B分佈,是指一組定義在(0,1)區間的連續概率分佈。
在這裏插入圖片描述

chisqusre():生成卡方分佈的隨機數

gamma():生成gamma分佈的隨機數

伽瑪分佈(Gamma Distribution)是統計學的一種連續概率函數,是概率統計中一種非常重要的分佈。“指數分佈”和“χ2分佈”都是伽馬分佈的特例。

二、數據類型

(一)基本數據類型

(二)數據類型轉換

# 例
print(np.float64(42))
print(np.int32(42.0))
print(np.bool(1))    # 所有非零數據轉換成bool類型都是True

(三)自定義數據類型

例:創建一個存儲餐飲企業庫存信息的數據類型

規定:

(1)用一個長度爲40的字符串來記錄商品的名稱

(2)用一個64位整數來記錄商品庫存

(3)用一個64位單精度浮點型來記錄商品的價格

df = np.dtype([('name',np.str_,40),('numitems',np.int64),('price',np.float64)])
print('df數據結構:',df)    # [('name', '<U40'), ('numitems', '<i8'), ('price', '<f8')]
# <U40--長度小於40的字符串,<i8--小於八字節的int類型
table1 = np.array([('tomatos',42,4.14),('cabbages',13,1.72)],dtype=df)
print(table1)
# 輸出商品名
print(table1['name'])    # ['tomatos' 'cabbages']
print(table1[0],type(table1[0]))    # <class 'numpy.void'>
arr1 = np.array([1,2,3])
print(arr1[0],type(arr1[0]))    # <class 'numpy.int32'>

三、數據元素的訪問

通過索引訪問數組元素

(一)一維數組

arr1 = np.arange(10)
print(arr1)
print(arr1[0])
print(arr1[-1])
# 支持切片
print(arr1[3:5])
print(arr1[:5])
print(arr1[3:])

arr1[2:4] = 100,101    # 個數不對應,會報錯
print(arr1)    # [  0   1 100 101   4   5   6   7   8   9]
print(arr1[1:-1:2])
print(arr1[5:1:-2])

注意:從後向前利用切片取數組中的元素時,步長爲負。

(二)二維數組

arr2 = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
print(arr2)
# [[ 1  2  3  4]
#  [ 5  6  7  8]
#  [ 9 10 11 12]]
print(arr2[0][0])

例:取第一行,第3,4列的元素

1.切片

print(arr2[0][2:])

2.數組名[行索引,列索引]

print(arr2[0,2:])

3.數組名[(行下標),(列下標)]

說明:該種寫法主要用於獲取指定行或列的值;而切片寫法,獲取到的是連續的行或列的值。

print(arr2[(0,2),(1,3)])    # [ 2 12]
# 2--(0,2),12--(2,3)
# 也可以配合使用
print(arr2[(0,2),:])

(三)遮罩–mask

arr3 = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
mask = np.array([1,0,1],dtype=np.bool)
print(mask)    # [ True False  True],True顯示,False不顯示
print(arr3[mask,2])
print(arr3[(True,False,True),2])

四、變換數組形態

(一)shape和reshape()

arr1 = np.arange(0,15)
arr1.shape = (3,5)
print(arr1)
arr2 = np.arange(0,15).reshape(3,5)
print(arr2)

(二)展平數組

1.ravel()

是reshape()函數的逆操作

注意:並不修改原數組,而是返回了一個新數組。

arr1 = np.arange(10000)
arr2 = arr1.reshape((100,100))
print(arr1)
print(arr2)
arr3 = arr2.ravel()
print(arr3)

tip1

如果輸出的數組數量太大,在輸出時,numpy自動省略中間部分,只打印兩邊元素。

如果不想省略,可以在打印前設置如下信息:

np.set_printoptions(threshold=np.NaN)
# 之後再打印
print(arr2)

2.flatten()

# 默認order='C'		
# 以行展平
arr3 = np.arange(10).reshape((2,5))
arr4 = arr3.flatten()
arr5 = arr3.ravel()
print(arr3)
print(arr4)
print(arr5)

# order='F'
# 以列展平
arr6 = np.array([[1,2],[3,4]])
arr7 = arr6.flatten(order='F')
print(arr7)

ravel()和flatten()

共同點

都是將多維數組展開爲一維,輸出結果相同。

不同點

flatten返回的是一份拷貝,強調的是數據。

ravel返回的是一份視圖,側重的是數據的展現,而不是數據本身。

例:

a1 = np.array([[1,2],[3,4]])
f_a = a1.flatten()
r_a = a1.ravel()
print(a1)
print('f_a:',f_a)
print('r_a:',r_a)
print('--------------------------------------------------------')
f_a[2] = 100
print('f_a:',f_a)
print(a1)    # flatten的數組元素髮生變化不影響原數組

a1 = np.array([[1,2],[3,4]])
f_a = a1.flatten()
r_a = a1.ravel()
print(a1)
print('f_a:',f_a)
print('r_a:',r_a)
print('--------------------------------------------------------')
r_a[2] = 101
print('r_a:',r_a)
print(a1)    # ravel的數組元素變化,原數據也會同時發生變化

(三)組合/切割數組

1.組合

(1)hstack()和vstack()

arr1 = np.arange(1,6,2)
arr2 = np.arange(7,12,2)
print(arr1,arr2)    # [1 3 5] [ 7  9 11]
arr3 = np.hstack((arr1,arr2))
print(arr3)
# [ 1  3  5  7  9 11]
arr4 = np.vstack((arr1,arr2))
print(arr4)
# [[ 1  3  5]
#  [ 7  9 11]]

注意

如果兩個數組,元素個數不相等,橫向正常拼接,但縱向將會報錯。

在stack函數中,參數爲tuple,但其實list也是可以的。

arr1 = np.array([[1,1],[2,2]])
arr2 = np.array([[3,3],[4,4]])
arr3 = np.hstack((arr1,arr2))
arr4 = np.vstack((arr1,arr2))
print('arr1:\n',arr1)
# arr1:
#  [[1 1]
#  [2 2]]
print('arr2:\n',arr2)
# arr2:
#  [[3 3]
#  [4 4]]
print('arr3:\n',arr3)
# arr3:
#  [[1 1 3 3]
#  [2 2 4 4]]
print('arr4:\n',arr4)
# arr4:
#  [[1 1]
#  [2 2]
#  [3 3]
#  [4 4]]

(2)concatenate()和軸

axis–軸

# 橫向拼接
arr5 = np.concatenate((arr1,arr2),axis=1)
print('arr5:\n',arr5)
# 縱向拼接
arr6 = np.concatenate((arr1,arr2),axis=0)
print('arr6:\n',arr6)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章