pandas之樣本操作
阿新 • • 發佈:2021-12-05
隨機抽樣,是統計學中常用的一種方法,它可以幫助我們從大量的資料中快速地構建出一組資料分析模型。在 Pandas 中,如果想要對資料集進行隨機抽樣,需要使用 sample() 函式。
sample() 函式的語法格式如下:
DataFrame.sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None)
引數說明如下表所示:
引數名稱 | 引數說明 |
---|---|
n | 表示要抽取的行數。 |
frac | 表示抽取的比例,比如 frac=0.5,代表抽取總體資料的50%。 |
replace | 布林值引數,表示是否以有放回抽樣的方式進行選擇,預設為 False,取出資料後不再放回。 |
weights | 可選引數,代表每個樣本的權重值,引數值是字串或者陣列。 |
random_state | 可選引數,控制隨機狀態,預設為 None,表示隨機資料不會重複;若為 1 表示會取得重複資料。 |
axis | 表示在哪個方向上抽取資料(axis=1 表示列/axis=0 表示行)。 |
該函式返回與資料集型別相同的新物件,相當於 numpy.random.choice()。例項如下:
- import pandas as pd
- dict = {'name':["Jack", "Tom", "Helen", "John"],'age': [28, 39, 34, 36],'score':[98,92,91,89]}
- info = pd.DataFrame(dict)
- #預設隨機選擇兩行
- info.sample(n=2)
- #隨機選擇兩列
- info.sample(n=2,axis=1)
輸出結果:
name age score 3 John 36 89 0 Jack 28 98 score name 0 98 Jack 1 92 Tom 2 91 Helen 3 89 John
再來看一組示例:
- import pandas as pd
- info = pd.DataFrame({'data1': [2, 6, 8, 0], 'data2': [2, 5, 0, 8], 'data3': [12, 2, 1, 8]}, index=['John', 'Parker', 'Smith', 'William'])
- info
- #隨機抽取3個數據
- info['data1'].sample(n=3)
- #總體的50%
- info.sample(frac=0.5, replace=True)
- #data3序列為權重值,並且允許重複資料出現
- info.sample(n=2, weights='data3', random_state=1)
輸出結果:
隨機選擇3行資料: William 0 Smith 8 Parker 6 Name: data1, dtype: int64 data1 data2 data3 John 2 2 12 William 0 8 8 data1 data2 data3 John 2 2 12 William 0 8 8
---------------------------------------------------
資料重取樣是將時間序列從一個頻率轉換至另一個頻率的過程,它主要有兩種實現方式,分別是降取樣和升取樣,降取樣指將高頻率的資料轉換為低頻率,升取樣則與其恰好相反,說明如下:
方法 | 說明 |
---|---|
降取樣 | 將高頻率(間隔短)資料轉換為低頻率(間隔長)。 |
升取樣 | 將低頻率資料轉換為高頻率。 |
Pandas 提供了 resample() 函式來實現資料的重取樣。
降取樣
通過 resample() 函式完成資料的降取樣,比如按天計數的頻率轉換為按月計數。
- import pandas as pd
- import numpy as np
- rng = pd.date_range('1/1/2021',periods=100,freq='D')
- ts = pd.Series(np.random.randn(len(rng)),index=rng)
- #降取樣後並聚合
- ts.resample('M').mean()
輸出結果:
2021-01-31 0.210353 2021-02-28 -0.058859 2021-03-31 -0.182952 2021-04-30 0.205254 Freq: M, dtype: float64
如果您只想看到月份,那麼您可以設定kind=period
如下所示:
ts.resample('M',kind='period').mean()
輸出結果:
2021-01 -0.153121 2021-02 0.136231 2021-03 -0.238975 2021-04 -0.309502 Freq: M, dtype: float64
升取樣
升取樣是將低頻率(時間間隔)轉換為高頻率,示例如下:
- import pandas as pd
- import numpy as np
- #生成一份時間序列資料
- rng = pd.date_range('1/1/2021', periods=20, freq='3D')
- ts = pd.Series(np.random.randn(len(rng)), index=rng)
- print(ts.head())
- #使用asfreq()在原資料基礎上實現頻率轉換
- ts.resample('D').asfreq().head()
輸出結果:
升取樣前: 2021-01-01 0.608716 2021-01-04 1.097451 2021-01-07 -1.280173 2021-01-10 -0.175065 2021-01-13 1.046831 Freq: 3D, dtype: float64 升取樣後: 2021-01-01 0.608716 2021-01-02 NaN 2021-01-03 NaN 2021-01-04 1.097451 2021-01-05 NaN Freq: D, dtype: float64
頻率轉換
asfreq() 方法不僅能夠實現頻率轉換,還可以保留原頻率對應的數值,同時它也可以單獨使用,示例如下:
- index = pd.date_range('1/1/2021', periods=6, freq='T')
- series = pd.Series([0.0, None, 2.0, 3.0,4.0,5.0], index=index)
- df = pd.DataFrame({'s':series})
- print(df.asfreq("45s"))
輸出結果:
num 2021-01-01 00:00:00 0.0 2021-01-01 00:00:45 NaN 2021-01-01 00:01:30 NaN 2021-01-01 00:02:15 NaN 2021-01-01 00:03:00 3.0 2021-01-01 00:03:45 NaN 2021-01-01 00:04:30 NaN
插值處理
從上述示例不難看出,升取樣的結果會產生缺失值,那麼就需要對缺失值進行處理,一般有以下幾種處理方式:
方法 | 說明 |
---|---|
pad/ffill | 用前一個非缺失值去填充缺失值。 |
backfill/bfill | 用後一個非缺失值去填充缺失值。 |
interpolater('linear') | 線性插值方法。 |
fillna(value) | 指定一個值去替換缺失值。 |
下面使用插值方法處理 NaN 值,示例如下:
- import pandas as pd
- import numpy as np
- #建立時間序列資料
- rng = pd.date_range('1/1/2021', periods=20, freq='3D')
- ts = pd.Series(np.random.randn(len(rng)), index=rng)
- print(ts.resample('D').asfreq().head())
- #使用ffill處理缺失值
- ts.resample('D').asfreq().ffill().head()
輸出結果:
2021-01-01 0.555580 2021-01-02 NaN 2021-01-03 NaN 2021-01-04 -0.079324 2021-01-05 NaN Freq: D, dtype: float64 #插值處理,注意對比 2021-01-01 0.555580 2021-01-02 0.555580 2021-01-03 0.555580 2021-01-04 -0.079324 2021-01-05 -0.079324 Freq: D, dtype: float64