pandas 學習 第3篇:Series - 數據處理(應用、分組、滾動、擴展、指數加權移動平均)


序列內置一些函數,用於循環對序列的元素執行操作。

一,應用和轉換函數

應用apply

對序列的各個元素應用函數:

Series.apply(self, func, convert_dtype=True, args=(), **kwds)

參數注釋:

  • func:應用的函數,可以是自定義的函數,或NumPy函數
  • convert_dtype:默認值是True,嘗試把func應用的結果轉換為更好的數據類型,如果設置為False,把結果轉換為dtype=object.
  • args:元組,在序列值之后,傳遞給func的位置參數(positional arguments)
  • **kwds:傳遞給func的關鍵字(keyword)參數,可以有0、1、多個

位置參數和關鍵字參數的區別是:

  • 位置參數是通過匹配位置來傳參,關鍵字參數是通過匹配參數名稱來傳參。
  • 關鍵字參數可以有多個,參數的名稱不固定,只能在apply函數()的最后面,例如,關鍵字參數k1,k2,k3,那么kwargs=[k1,k2,k3]
  • 位置參數args只能有一個

1,傳遞自定義的函數(使用位置參數)

創建自定義的函數,把函數應用於序列之上

>>> s = pd.Series([20, 21, 12], index=['London', 'New York', 'Helsinki'])
>>> def subtract_custom_value(x, custom_value):
...     return x - custom_value
>>> s.apply(subtract_custom_value, args=(5,))
London      15
New York    16
Helsinki     7
dtype: int64

2,傳遞自定義的函數(使用關鍵字參數)

可以看到,關鍵字參數只能在apply函數的后面,

>>> def add_custom_values(x, **kwargs):
...     for month in kwargs:
...         x += kwargs[month]
...     return x
>>> s.apply(add_custom_values, june=30, july=20, august=25)
London      95
New York    96
Helsinki    87
dtype: int64

轉換transform

轉換是對序列的一個軸進行轉換,對於序列來說,axis=0,對行序列進行轉換:

Series.transform(self, func, axis=0, *args, **kwargs)

二,分組

對序列分組,返回分組之后的對象,並可以調用聚合函數獲得每個分組的聚合值:

Series.groupby(self, by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False, **kwargs)

參數注釋:

by:用於對序列進行分組,參數by的值可以是函數,列名或列名列表,映射

1,by是函數

如果by是函數,那么調用的是序列索引的值

>>> s=pd.Series([1,2,3,4])
>>> s.groupby(by=lambda x: x<3).count()
False    1
True     3
dtype: int64

可以通過索引值來訪問序列的元素值:

>>> s.groupby(by=lambda x: s.iat[x]<3).count()
False    2
True     2
dtype: int64

2,by是標簽列表

如果by是標簽列表,通常是按照列值來對數據進行分組,通常用於數據框(DataFrame)中

3,映射(字典)

當使用字典作為映射時,字典的key對應序列的值,按照字典的value對原始序列進行分組

>>> s.groupby(by={1:'a',2:'a',3:'b',4:'b'}).count()
a    2
b    1
dtype: int64

4,映射(序列)

當使用序列作為映射時,by序列的值用於對原始序列進行分組,by序列中相同的值對應着原始序列的值屬於同一個分組;原始序列和by序列進行匹配的方法是索引對齊。

>>> s.groupby(by=pd.Series(data=[1,2,1,1],index=[0,2,3,1])).mean()
1    2.333333
2    3.000000
dtype: float64

索引對齊是怎么回事?

對於by參數的序列,數據是1, 2, 1, 1,這意味着,把原始序列分為2組,分組的key分別是1和2。

by序列的索引是0, 2, 3, 1,也就是說,當原始序列的索引為0, 3, 1 時,對應的分組key是1,當原始序列的索引為2時,對應的分組key是2。

索引對齊之后,原始序列中的值1,2,4屬於分組1;原始序列中的值3屬於分組2,再計算每個分組的均值。

三,滾動

滾動窗口計算,每個窗口計算一個聚合值,每次向前滾動一步(一步是一個元素):

Series.rolling(self, window, min_periods=None, center=False, win_type=None, on=None, axis=0, closed=None)

參數注釋:

  • window:滾動的窗口值,或偏移量,每一個窗口都是一個固定值。
  • min_periods:每個窗口的最小值,如果窗口中的元素數量小於min_periods,返回NaN;默認情況下,min_periods等於window參數的值。

舉個例子,對於序列,當窗口設置為2時,如果不設置min_periods,那么窗口要想有值,那么窗口的大小必須是2,序列的第一個元素在窗口中只有一個值,因此返回NaN。

>>> s=pd.Series([1,2,3,4])
>>> s.rolling(2).sum()
0    NaN
1    3.0
2    5.0
3    7.0
dtype: float64
>>> s.rolling(window=2,min_periods =1).sum()
0    1.0
1    3.0
2    5.0
3    7.0
dtype: float64

四,擴展

擴展是指由序列的第一個元素開始,逐個元素向后計算聚合值,當聚合函數是sum時,表示從第一個元素開始,計算累加:

Series.expanding(self, min_periods=1, center=False, axis=0)

舉個例子,從第一個元素開始計算序列1,2,3,4的累加:

>>> s=pd.Series([1,2,3,4])
>>> s.expanding().sum()
0     1.0
1     3.0
2     6.0
3    10.0
dtype: float64

五,指數加權移動平均

ewm(Exponentially Weighted Moving)是指數加權移動的簡稱,通常情況下,是對序列的元素進行指數加權,計算加權后的均值:

Series.ewm(self, com=None, span=None, halflife=None, alpha=None, min_periods=0, adjust=True, ignore_na=False, axis=0)

1,參數注釋

在進行指數加權時,平滑因子有四種指定方式得出:

adjust:處於初期的衰減調整因子,以解決相對權重不平衡的問題。

  • 當設置adjust為True時,加權均值的計算公式是: (1-alpha)**(n-1), (1-alpha)**(n-2), …, 1-alpha, 1
  • 當設置adjust為False時,加權均值的計算公式是:weighted_average[0] = arg[0]; weighted_average[i] = (1-alpha)*weighted_average[i-1] + alpha*arg[i].

2,指數加權移動平均的意義

指數加權移動均值(EWMA,Exponentially Weighted Moving Average) 的公式是:EWMA(t) = aY(t) + (1-a)EWMA(t-1),t = 1,2,.....,n;

表示的含義是:在t時刻,根據實際的觀測值可以求取EWMA(t),其中,EWMA(t)  表示 t 時刻的估計值;Y(t) t時刻的測量值;n 所觀察的總的時間;a(0 < a <1)表示對於歷史測量值權重系數。

之所以稱之為指數加權,是因為加權系數a是以指數式遞減的,即各指數隨着時間而呈現出指數式遞減。系數a越接近1表示對當前抽樣值的權重越高,對過去測量值得權重越低,估計值(器)的時效性就越強,反之,越弱。

這種現象可以描述為應付突變的平穩性,平穩性隨着a的增大而減小。當設置較小的系數a時,得出的均值更大程度上是參考過去的測量值,在較小程度上參考當前值,表現出很強的平穩性;當設置較大的系數a,得出的均值更大程度上是參考當前的測量值,表現出很強的波動性。舉個例子,對於序列,設置較大的指數a=0.8和較小的指數a=0.2,位置越靠后,得出的均值越接近或越遠離當前值:

>>> s=pd.Series([1,2,3,4])
>>> s.ewm(alpha=0.8).mean()
0    1.000000
1    1.833333
2    2.774194
3    3.756410
dtype: float64
>>> s.ewm(alpha=0.2).mean()
0    1.000000
1    1.555556
2    2.147541
3    2.775068
dtype: float64

 

 

 

參考文檔:

pandas.Series.apply


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM