數據分析篇 | Pandas數據結構之Series

  • 2019 年 12 月 11 日
  • 筆記

以下文章來源於Python大咖談,作者吱吱不倦的呆鳥

  • Series 類似多維數組
  • Series 類似字典
  • 矢量操作與對齊 Series 標籤
  • 名稱屬性

本節介紹 Pandas 基礎數據結構,包括各類對象的數據類型、索引、軸標記、對齊等基礎操作。首先,導入 NumPy 和 Pandas:

In [1]: import numpy as np    In [2]: import pandas as pd  

數據對齊是內在的」,這一原則是根本。除非顯式指定,Pandas 不會斷開標籤和數據之間的連接。

下文先簡單介紹數據結構,然後再分門別類介紹每種功能與方法。

Series

Series 是帶標籤的一維數組,可存儲整數、浮點數、字元串、Python 對象等類型的數據。軸標籤統稱為索引。調用 pd.Series 函數即可創建 Series:

>>> s = pd.Series(data, index=index)  

上述程式碼中,data 支援以下數據類型:

  • Python 字典
  • 多維數組
  • 標量值(如,5)

index 是軸標籤列表。不同數據可分為以下幾種情況:

多維數組

data 是多維數組時,index 長度必須與 data 長度一致。沒有指定 index 參數時,創建數值型索引,即 [0, ..., len(data) - 1]

In [3]: s = pd.Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])    In [4]: s  Out[4]:  a    0.469112  b   -0.282863  c   -1.509059  d   -1.135632  e    1.212112  dtype: float64    In [5]: s.index  Out[5]: Index(['a', 'b', 'c', 'd', 'e'], dtype='object')    In [6]: pd.Series(np.random.randn(5))  Out[6]:  0   -0.173215  1    0.119209  2   -1.044236  3   -0.861849  4   -2.104569  dtype: float64  

Pandas 的索引值可以重複。不支援重複索引值的操作會觸發異常。其原因主要與性能有關,有很多計算實例,比如 GroupBy 操作就不用索引。

字典

Series 可以用字典實例化:

In [7]: d = {'b': 1, 'a': 0, 'c': 2}    In [8]: pd.Series(d)  Out[8]:  b    1  a    0  c    2  dtype: int64  

data 為字典,且未設置 index 參數時,如果 Python 版本 >= 3.6 且 Pandas 版本 >= 0.23,Series 按字典的插入順序排序索引。 Python < 3.6 或 Pandas < 0.23,且未設置 index 參數時,Series 按字母順序排序字典的鍵(key)列表。

上例中,如果 Python < 3.6 或 Pandas < 0.23,Series 按字母排序字典的鍵。輸出結果不是 ['b', 'a', 'c'],而是 ['a', 'b', 'c']

如果設置了 index 參數,則按索引標籤提取 data 里對應的值。

In [9]: d = {'a': 0., 'b': 1., 'c': 2.}    In [10]: pd.Series(d)  Out[10]:  a    0.0  b    1.0  c    2.0  dtype: float64    In [11]: pd.Series(d, index=['b', 'c', 'd', 'a'])  Out[11]:  b    1.0  c    2.0  d    NaN  a    0.0  dtype: float64  

Pandas 用 NaN(Not a Number)表示缺失數據

標量值

data 是標量值時,必須提供索引。Series索引長度重複該標量值。

In [12]: pd.Series(5., index=['a', 'b', 'c', 'd', 'e'])  Out[12]:  a    5.0  b    5.0  c    5.0  d    5.0  e    5.0  dtype: float64  

Series 類似多維數組

Series 操作與 ndarray 類似,支援大多數 NumPy 函數,還支援索引切片。

In [13]: s[0]  Out[13]: 0.4691122999071863    In [14]: s[:3]  Out[14]:  a    0.469112  b   -0.282863  c   -1.509059  dtype: float64    In [15]: s[s > s.median()]  Out[15]:  a    0.469112  e    1.212112  dtype: float64    In [16]: s[[4, 3, 1]]  Out[16]:  e    1.212112  d   -1.135632  b   -0.282863  dtype: float64    In [17]: np.exp(s)  Out[17]:  a    1.598575  b    0.753623  c    0.221118  d    0.321219  e    3.360575  dtype: float64  

索引與選擇數據一節介紹了 s[[4, 3, 1]] 等數組索引操作。

和 NumPy 數組一樣,Series 也支援 dtype

In [18]: s.dtype  Out[18]: dtype('float64')  

Series 的數據類型一般是 NumPy 數據類型。不過,Pandas 和第三方庫在一些方面擴展了 NumPy 類型系統,即擴展數據類型。比如,Pandas 的類別型數據與可空整數數據類型。更多資訊,請參閱數據類型 。

Series.array 用於提取 Series 數組。

In [19]: s.array  Out[19]:  <PandasArray>  [ 0.4691122999071863, -0.2828633443286633, -1.5090585031735124,   -1.1356323710171934,  1.2121120250208506]  Length: 5, dtype: float64  

執行不用索引的操作時,如禁用自動對齊,訪問數組非常有用。

Series.array 一般是擴展數組。簡單說,擴展數組是把 N 個 numpy.ndarray 包在一起的打包器。Pandas 知道怎麼把擴展數組存儲到 SeriesDataFrame 的列里。更多資訊,請參閱數據類型。

Series 只是類似於多維數組,提取真正的多維數組,要用 Series.to_numpy()

In [20]: s.to_numpy()  Out[20]: array([ 0.4691, -0.2829, -1.5091, -1.1356,  1.2121])  

Series 是擴展數組Series.to_numpy() 返回的是 NumPy 多維數組。

Series 類似字典

Series 類似固定大小的字典,可以用索引標籤提取值或設置值:

In [21]: s['a']  Out[21]: 0.4691122999071863    In [22]: s['e'] = 12.    In [23]: s  Out[23]:  a     0.469112  b    -0.282863  c    -1.509059  d    -1.135632  e    12.000000  dtype: float64    In [24]: 'e' in s  Out[24]: True    In [25]: 'f' in s  Out[25]: False  

引用 Series 里沒有的標籤會觸發異常:

>>> s['f']  KeyError: 'f'  

get 方法可以提取 Series 里沒有的標籤,返回 None 或指定默認值:

In [26]: s.get('f')    In [27]: s.get('f', np.nan)  Out[27]: nan  

更多資訊,請參閱屬性訪問。

矢量操作與對齊 Series 標籤

Series 和 NumPy 數組一樣,都不用循環每個值,而且 Series 支援大多數 NumPy 多維數組的方法。

In [28]: s + s  Out[28]:  a     0.938225  b    -0.565727  c    -3.018117  d    -2.271265  e    24.000000  dtype: float64    In [29]: s * 2  Out[29]:  a     0.938225  b    -0.565727  c    -3.018117  d    -2.271265  e    24.000000  dtype: float64    In [30]: np.exp(s)  Out[30]:  a         1.598575  b         0.753623  c         0.221118  d         0.321219  e    162754.791419  dtype: float64  

Series 和多維數組的主要區別在於, Series 之間的操作會自動基於標籤對齊數據。因此,不用顧及執行計算操作的 Series 是否有相同的標籤。

In [31]: s[1:] + s[:-1]  Out[31]:  a         NaN  b   -0.565727  c   -3.018117  d   -2.271265  e         NaN  dtype: float64  

操作未對齊索引的 Series, 其計算結果是所有涉及索引的並集。如果在 Series 里找不到標籤,運算結果標記為 NaN,即缺失值。編寫無需顯式對齊數據的程式碼,給交互數據分析和研究提供了巨大的自由度和靈活性。Pandas 數據結構集成的數據對齊功能,是 Pandas 區別於大多數標籤型數據處理工具的重要特性。

總之,讓不同索引對象操作的默認結果生成索引並集,是為了避免資訊丟失。就算缺失了數據,索引標籤依然包含計算的重要資訊。當然,也可以用dropna 函數清除含有缺失值的標籤。

名稱屬性

Series 支援 name 屬性:

In [32]: s = pd.Series(np.random.randn(5), name='something')    In [33]: s  Out[33]:  0   -0.494929  1    1.071804  2    0.721555  3   -0.706771  4   -1.039575  Name: something, dtype: float64    In [34]: s.name  Out[34]: 'something'  

一般情況下,Series 自動分配 name,特別是提取一維 DataFrame 切片時,詳見下文。

0.18.0 版新增。

pandas.Series.rename() 方法用於重命名 Series 。

In [35]: s2 = s.rename("different")    In [36]: s2.name  Out[36]: 'different'  

注意,ss2 指向不同的對象。

【完】