1. 程式人生 > 其它 >pandas之樣本操作

pandas之樣本操作

隨機抽樣,是統計學中常用的一種方法,它可以幫助我們從大量的資料中快速地構建出一組資料分析模型。在 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()。例項如下:

  1. import pandas as pd
  2. dict = {'name':["Jack", "Tom", "Helen", "John"],'age': [28, 39, 34, 36],'score':[98,92,91,89]}
  3. info = pd.DataFrame(dict)
  4. #預設隨機選擇兩行
  5. info.sample(n=2)
  6. #隨機選擇兩列
  7. 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

再來看一組示例:

  1. import pandas as pd
  2. info = pd.DataFrame({'data1': [2, 6, 8, 0], 'data2': [2, 5, 0, 8], 'data3': [12, 2, 1, 8]}, index=['John', 'Parker', 'Smith', 'William'])
  3. info
  4. #隨機抽取3個數據
  5. info['data1'].sample(n=3)
  6. #總體的50%
  7. info.sample(frac=0.5, replace=True)
  8. #data3序列為權重值,並且允許重複資料出現
  9. 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() 函式完成資料的降取樣,比如按天計數的頻率轉換為按月計數。
  1. import pandas as pd
  2. import numpy as np
  3. rng = pd.date_range('1/1/2021',periods=100,freq='D')
  4. ts = pd.Series(np.random.randn(len(rng)),index=rng)
  5. #降取樣後並聚合
  6. 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

升取樣

升取樣是將低頻率(時間間隔)轉換為高頻率,示例如下:
  1. import pandas as pd
  2. import numpy as np
  3. #生成一份時間序列資料
  4. rng = pd.date_range('1/1/2021', periods=20, freq='3D')
  5. ts = pd.Series(np.random.randn(len(rng)), index=rng)
  6. print(ts.head())
  7. #使用asfreq()在原資料基礎上實現頻率轉換
  8. 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() 方法不僅能夠實現頻率轉換,還可以保留原頻率對應的數值,同時它也可以單獨使用,示例如下:
  1. index = pd.date_range('1/1/2021', periods=6, freq='T')
  2. series = pd.Series([0.0, None, 2.0, 3.0,4.0,5.0], index=index)
  3. df = pd.DataFrame({'s':series})
  4. 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 值,示例如下:
  1. import pandas as pd
  2. import numpy as np
  3. #建立時間序列資料
  4. rng = pd.date_range('1/1/2021', periods=20, freq='3D')
  5. ts = pd.Series(np.random.randn(len(rng)), index=rng)
  6. print(ts.resample('D').asfreq().head())
  7. #使用ffill處理缺失值
  8. 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