背景Numpy 提供的最重要的數(shù)據(jù)結(jié)構(gòu)是 ndarray,,它是 Python 中 list 的擴(kuò)展,。 Pandas 提供了兩種非常重要的數(shù)據(jù)結(jié)構(gòu) Series和DataFrame,。 Numpy 中的一維數(shù)組與 Series 相似,,一維數(shù)組只是提供了從0開始與位置有關(guān)的索引,,而Series除了位置索引之外還可以附加額外的索引,。本文將從對(duì)象的創(chuàng)建,、屬性的訪問,、數(shù)據(jù)的獲取以及常用方法等方面來總結(jié)這兩種結(jié)構(gòu)的異同。 1. 如何創(chuàng)建對(duì)象1.1 創(chuàng)建一維數(shù)組對(duì)象 - 通過 list或tuple 創(chuàng)建一維數(shù)組。
- 通過數(shù)值范圍來創(chuàng)建一維數(shù)組,,比如
linspace() 函數(shù),,返回指定間隔內(nèi)的等間隔數(shù)字。arange() 函數(shù),,返回給定間隔內(nèi)的均勻間隔的值,。
import numpy as np
a0 = np.array((10, 40, 5, 90, 35, 40)) print(a0) # [10 40 5 90 35 40]
a1 = np.array([10, 40, 5, 90, 35, 40]) print(a1) # [10 40 5 90 35 40]
a2 = np.linspace(start=0, stop=5, num=5) print(a2) # [0. 1.25 2.5 3.75 5. ]
a3 = np.arange(10, 15) print(a3) # [10 11 12 13 14]
1.2 創(chuàng)建Series對(duì)象 Series 可以看作是能夠附加索引的一維數(shù)組,所以可以像 Numpy 創(chuàng)建一維數(shù)組一樣使用 list或tuple 來創(chuàng)建,,甚至可以使用 Numpy的一維數(shù)組 直接創(chuàng)建,。 - 通過列表
list 、元組tuple 創(chuàng)建Series ,。 - 通過 Numpy 創(chuàng)建
Series ,。
另外,Series 可以附加索引,,所以可以在創(chuàng)建的時(shí)候直接指定需要附加的索引,,以及利用字典的key-value 鍵值對(duì) 來直接創(chuàng)建。 - 通過指定
index 關(guān)鍵字的方式創(chuàng)建帶有自定義索引的Series ,。 - 通過字典
dict 創(chuàng)建Series ,。
import pandas as pd import numpy as np
s0 = pd.Series((10, 40, 5, 90, 35, 40)) print(s0) # 0 10 # 1 40 # 2 5 # 3 90 # 4 35 # 5 40 # dtype: int64
s1 = pd.Series([10, 40, 5, 90, 35, 40]) print(s1) # 0 10 # 1 40 # 2 5 # 3 90 # 4 35 # 5 40 # dtype: int64
s2 = pd.Series(np.linspace(start=0, stop=5, num=5)) print(s2) # 0 0.00 # 1 1.25 # 2 2.50 # 3 3.75 # 4 5.00 # dtype: float64
s3 = pd.Series(np.arange(10, 15)) print(s3) # 0 10 # 1 11 # 2 12 # 3 13 # 4 14 # dtype: int32
s4 = pd.Series([100, 79, 65, 77], index=["chinese", "english", "history", "maths"], name='score') print(s4) # chinese 100 # english 79 # history 65 # maths 77 # Name: score, dtype: int64
s5 = pd.Series({"name": "張三", "Gender": "男", "age": 20, "height": 180, "weight": 66}) print(s5) # name 張三 # Gender 男 # age 20 # height 180 # weight 66 # dtype: object
2. 如何獲取屬性2.1 獲取一維數(shù)組對(duì)象屬性 在使用 Numpy 時(shí),有時(shí)會(huì)想知道數(shù)組的某些信息,,可以通過以下屬性來得到: numpy.ndarray.ndim 用于返回?cái)?shù)組的維數(shù)(軸的個(gè)數(shù))也稱為秩,,一維數(shù)組的秩為 1,二維數(shù)組的秩為 2,,以此類推,。numpy.ndarray.shape 表示數(shù)組的維度,返回一個(gè)元組,,這個(gè)元組的長度就是維度的數(shù)目,,即 ndim 屬性(秩)。numpy.ndarray.size 數(shù)組中所有元素的總量,,相當(dāng)于數(shù)組的shape 中所有元素的乘積,,例如矩陣的元素總量為行與列的乘積。numpy.ndarray.dtype ndarray 對(duì)象的元素類型,。
import numpy as np
a0 = np.array([10, 40, 5, 90, 35, 40]) print(a0.ndim) # 1 print(a0.size) # 6 print(a0.shape) # (6,) print(a0.dtype) # int32
2.2 獲取Series對(duì)象屬性 Series 除了擁有 Numpy 中ndim ,、size 、shap ,、dtype 屬性外,,還擁有下列屬性: values 存儲(chǔ)的數(shù)據(jù)
import pandas as pd
s0 = pd.Series((10, 40, 5, 90, 35, 40)) print(s0.ndim) # 1 print(s0.size) # 6 print(s0.shape) # (6,) print(s0.dtype) # int64 print(s0.index) # RangeIndex(start=0, stop=6, step=1) print(s0.values) # [10 40 5 90 35 40] print(s0.name) # None
s1 = pd.Series([100, 79, 65, 77], index=["chinese", "english", "history", "maths"], name='score') print(s1.index) # Index(['chinese', 'english', 'history', 'maths'], dtype='object')
print(s1.values) # [100 79 65 77]
3. 如何獲取數(shù)據(jù)3.1 獲取一維數(shù)組對(duì)象數(shù)據(jù) 一維數(shù)組只有默認(rèn)的位置索引,即從0開始的索引,,所以獲取數(shù)據(jù)只有通過位置索引這一種方式,。 - 通過整數(shù)索引(要獲取數(shù)組的單個(gè)元素,,指定元素的索引即可。)
- 通過切片索引(切片操作是指抽取數(shù)組的一部分元素生成新數(shù)組,。)
- 通過整數(shù)數(shù)組索引(方括號(hào)內(nèi)傳入多個(gè)索引值,,可以同時(shí)選擇多個(gè)元素。)
- 通過布爾索引(通過一個(gè)布爾數(shù)組來索引目標(biāo)數(shù)組,。)
import numpy as np
a0 = np.array([10, 40, 5, 90, 35, 40]) print(a0[0]) # 10 print(a0[0:2]) # [10 40] print(a0[2:]) # [ 5 90 35 40] print(a0[0::2]) # [10 5 35] print(a0[[0, 1, 2]]) # [10 40 5] print(a0[:5]) # [10 40 5 90 35] print(a0[-5:]) # [40 5 90 35 40] print(a0[a0 > 35]) # [40 90 40] print(a0[a0 != 35]) # [10 40 5 90 40]
3.2 獲取Series對(duì)象數(shù)據(jù) 因?yàn)椴桓郊铀饕?Series 也擁有位置索引,,所以可以延用一維數(shù)組獲取數(shù)據(jù)的方式。另外 Series 也可以通過附加索引來獲取數(shù)據(jù),。 - 通過
head() 和tail() 獲取數(shù)據(jù)
import pandas as pd
s0 = pd.Series((10, 40, 5, 90, 35, 40)) print(s0[0]) # 10 print(s0[0:2]) # 0 10 # 1 40 # dtype: int64 print(s0[2:]) # 2 5 # 3 90 # 4 35 # 5 40 # dtype: int64 print(s0[0::2]) # 0 10 # 2 5 # 4 35 # dtype: int64 print(s0.head()) # 0 10 # 1 40 # 2 5 # 3 90 # 4 35 # dtype: int64 print(s0.tail()) # 1 40 # 2 5 # 3 90 # 4 35 # 5 40 # dtype: int64 print(s0[[0, 1, 2]]) # 0 10 # 1 40 # 2 5 # dtype: int64
s1 = pd.Series([100, 79, 65, 77], index=["chinese", "english", "history", "maths"], name='score') print(s1["chinese"]) # 100 print(s1[["english", "history"]]) # english 79 # history 65 # dtype: int64 print(s1[s1.values > 70]) # chinese 100 # english 79 # maths 77 # Name: score, dtype: int64 print(s1[s1.index != 'chinese']) # english 79 # history 65 # maths 77 # Name: score, dtype: int64
s2 = pd.Series({"name": "張三", "Gender": "男", "age": 20, "height": 180, "weight": 66}) print(s2["name"]) # 張三 print(s2[["name", "height", "weight"]]) # name 張三 # height 180 # weight 66 # dtype: object
4. 基本運(yùn)算4.1 查看描述性統(tǒng)計(jì)數(shù)據(jù) 一維數(shù)組對(duì)象 描述性統(tǒng)計(jì)分析最常見的函數(shù)如下: numpy.min() 函數(shù):返回?cái)?shù)組的最小值或沿軸的最小值。numpy.max() 函數(shù):返回?cái)?shù)組的最大值或沿軸的最大值,。numpy.quantile() 函數(shù):計(jì)算沿指定軸的數(shù)據(jù)的分位數(shù),。numpy.median() 函數(shù):沿指定軸計(jì)算中位數(shù)。返回?cái)?shù)組元素的中位數(shù),。numpy.mean() 函數(shù):計(jì)算沿指定軸的算術(shù)平均值,。numpy.std() 函數(shù):計(jì)算沿指定軸的標(biāo)準(zhǔn)偏差。
import numpy as np
a0 = np.array([10, 40, 5, 90, 35, 40]) print(np.size(a0)) # 6 print(np.mean(a0)) # 36.666666666666664 print(np.std(a0, ddof=1)) # 30.276503540974915 print(np.max(a0)) # 90 print(np.min(a0)) # 5 print(np.median(a0)) # 37.5 print(np.quantile(a0, [.25, .5, .75])) # [16.25 37.5 40. ]
Series對(duì)象 除了一維數(shù)組所提供的函數(shù)之外,,Series也提供了更多的函數(shù)用于描述性統(tǒng)計(jì)分析,。 import pandas as pd
s0 = pd.Series((10, 40, 5, 90, 35, 40)) print(type(s0.values)) # <class 'numpy.ndarray'> print(s0.count()) # 6 print(s0.mean()) # 36.666666666666664 print(s0.std()) # 30.276503540974915 print(s0.max()) # 90 print(s0.min()) # 5 print(s0.median()) # 37.5 print(s0.quantile([.25, .5, .75])) # 0.25 16.25 # 0.50 37.50 # 0.75 40.00 # dtype: float64
print(s0.mode()) # 0 40 # dtype: int64 print(s0.value_counts()) # 40 2 # 35 1 # 5 1 # 90 1 # 10 1 # dtype: int64 print(s0.describe()) # count 6.000000 # mean 36.666667 # std 30.276504 # min 5.000000 # 25% 16.250000 # 50% 37.500000 # 75% 40.000000 # max 90.000000 # dtype: float64
4.2 數(shù)學(xué)運(yùn)算 一維數(shù)組對(duì)象 numpy.add() 函數(shù):按元素相加。numpy.subtract() 函數(shù):按元素相減,。numpy.multiply() 函數(shù):按元素相乘,。numpy.divide() 函數(shù):返回輸入的實(shí)際除法(按元素)。numpy.floor_divide() 函數(shù):返回小于或等于輸入除法的最大整數(shù)(地板除),。numpy.power() 函數(shù):按元素做冪運(yùn)算,。
在 Numpy 中對(duì)以上函數(shù)進(jìn)行了運(yùn)算符的重載,且運(yùn)算符為 元素級(jí),。也就是說,,它們只用于位置相同的元素之間,所得到的運(yùn)算結(jié)果組成一個(gè)新的數(shù)組,。 import numpy as np
a0 = np.array([10, 40, 5, 90, 35, 40]) print(a0 + 1) # [11 41 6 91 36 41] print(a0 - 1) # [ 9 39 4 89 34 39] print(a0 * 2) # [ 20 80 10 180 70 80] print(a0 / 2) # [ 5. 20. 2.5 45. 17.5 20. ] print(a0 // 2) # [ 5 20 2 45 17 20] print(a0 % 2) # [0 0 1 0 1 0] print(a0 ** 2) # [ 100 1600 25 8100 1225 1600]
print(np.sqrt(a0)) # [3.16227766 6.32455532 2.23606798 9.48683298 5.91607978 6.32455532] print(np.log(a0)) # [2.30258509 3.68887945 1.60943791 4.49980967 3.55534806 3.68887945]
Series對(duì)象 Series 與 Numpy 中的一維數(shù)組一樣支持常用運(yùn)算符的重載,,并且可以把 Series對(duì)象 作為參數(shù)帶入到 Numpy 的數(shù)學(xué)運(yùn)算中。 numpy.sqrt() 函數(shù):按元素返回?cái)?shù)組的非負(fù)平方根,。numpy.log() 函數(shù):按元素取自然對(duì)數(shù),。
import pandas as pd import numpy as np
s0 = pd.Series((10, 40, 5, 90, 35, 40)) print(type(s0.values)) # <class 'numpy.ndarray'> print(s0 + 1) # 0 11 # 1 41 # 2 6 # 3 91 # 4 36 # 5 41 # dtype: int64
print(s0 - 1) # 0 9 # 1 39 # 2 4 # 3 89 # 4 34 # 5 39 # dtype: int64
print(s0 * 2) # 0 20 # 1 80 # 2 10 # 3 180 # 4 70 # 5 80 # dtype: int64
print(s0 / 2) # 對(duì)每個(gè)值除2 # 0 5.0 # 1 20.0 # 2 2.5 # 3 45.0 # 4 17.5 # 5 20.0 # dtype: float64
print(s0 // 2) # 對(duì)每個(gè)值除2后取整 # 0 5 # 1 20 # 2 2 # 3 45 # 4 17 # 5 20 # dtype: int64
print(s0 % 2) # 取余 # 0 0 # 1 0 # 2 1 # 3 0 # 4 1 # 5 0 # dtype: int64
print(s0 ** 2) # 求平方 # 0 100 # 1 1600 # 2 25 # 3 8100 # 4 1225 # 5 1600 # dtype: int64
print(np.sqrt(s0)) # 求開方 # 0 3.162278 # 1 6.324555 # 2 2.236068 # 3 9.486833 # 4 5.916080 # 5 6.324555 # dtype: float64
print(np.log(s0)) # 求對(duì)數(shù) # 0 2.302585 # 1 3.688879 # 2 1.609438 # 3 4.499810 # 4 3.555348 # 5 3.688879 # dtype: float64
4.3 其它運(yùn)算 由于 Series 可以附加索引,所以兩個(gè) Series對(duì)象 進(jìn)行相加的時(shí)候,,必須滿足索引對(duì)齊,。另外,Series 可以通過to_numpy() 方法轉(zhuǎn)化成 Numpy 的一維數(shù)組,。 import pandas as pd import numpy as np
s1 = pd.Series({'a': 10, 'b': 40, 'c': 5, 'd': 90, 'e': 35, 'f': 40}, name='數(shù)值') s2 = pd.Series({'a': 10, 'b': 20, 'd': 23, 'g': 90, 'h': 35, 'i': 40}, name='數(shù)值') s3 = s1 + s2 print(s3) # a 20.0 # b 60.0 # c NaN # d 113.0 # e NaN # f NaN # g NaN # h NaN # i NaN # Name: 數(shù)值, dtype: float64 print(s3[s3.isnull()]) # c NaN # e NaN # f NaN # g NaN # h NaN # i NaN # Name: 數(shù)值, dtype: float64 print(s3[s3.notnull()]) # a 20.0 # b 60.0 # d 113.0 # Name: 數(shù)值, dtype: float64 s4 = s3.fillna(s3.mean()) print(s4) # a 20.000000 # b 60.000000 # c 64.333333 # d 113.000000 # e 64.333333 # f 64.333333 # g 64.333333 # h 64.333333 # i 64.333333 # Name: 數(shù)值, dtype: float64
a1 = s1.to_numpy() print(a1) # [10 40 5 90 35 40] a2 = s2.to_numpy() print(a2) # [10 20 23 90 35 40] a3 = s3.to_numpy() print(a3) # [ 20. 60. nan 113. nan nan nan nan nan] print(a3[np.logical_not(np.isnan(a3))]) # [ 20. 60. 113.] m = np.mean(a3[np.logical_not(np.isnan(a3))]) a4 = np.copy(a3) a4[np.argwhere(np.isnan(a4))] = m print(a4) # [ 20. 60. 64.33333333 113. 64.33333333 # 64.33333333 64.33333333 64.33333333 64.33333333]
總結(jié)我們通過實(shí)例從對(duì)象的創(chuàng)建,、屬性的獲取,、數(shù)據(jù)的訪問以及常用函數(shù)等維度對(duì)比了 Numpy 的一維數(shù)組和 Pandas 的 Series 結(jié)構(gòu)。很多知識(shí)都是相通的,,多對(duì)比多總結(jié)就會(huì)對(duì)整個(gè)模塊有更深入的了解,。今天就到這里吧,See You,。
|