1. 程式人生 > 其它 >Python學習筆記:高效資料格式feather(鴻毛)

Python學習筆記:高效資料格式feather(鴻毛)

一、背景

日常使用 Python 讀取資料時一般都是 jsoncsvtxtxlsx 等格式,或者直接從資料庫讀取。

針對大資料量一般儲存為 csv 格式,但檔案佔用空間比較大,儲存和載入速度也較慢。

feather 便是一種速度更快、更加輕量級(壓縮後)的二進位制儲存格式。

二、feather是什麼?

Feather 是一種用於儲存資料幀的資料格式。

一句話描述:高速讀寫壓縮二進位制檔案

Feather 其實是 Apache Arrow 專案中包含的一種資料格式,但是由於其優異的效能,該檔案格式也被單獨打包,放在 pip 中進行安裝。

Pandas 也支援對 Feather 的讀寫操作。

最初是為了 PythonR 之間快速互動而設計的,初衷很簡單,就是儘可能高效地完成資料在記憶體中轉換的效率。

難能可貴的是,RJuliapython 均可以解析 feather ,可以說是3種語言之間進行互動的強力工具了,讀寫速度一流。

現在 Feather 也不僅限於 PythonR ,基本每種主流的程式語言中都可以用 Feather 檔案。

不過,它的資料格式並不是為長期儲存而設計的,僅限於一般的短期儲存。

-- 此處不好理解:長期?短期?如何界定?

-- 如果長期儲存,feather 的空間壓縮並不是最好的,可以瞭解下 Parquet。feather也可以長期儲存,只不過不是最優解。

三、使用方法

Python 中,可以通過 pandasFeather 兩種方式進行操作。

但建議不要使用 pandas 自帶的 to_featherread_feather 。因為版本相容性的問題,直接使用 feather 自帶的 api 更優。

1.安裝

注意:不要直接使用 pip install feather 進行安裝,能正常顯示安裝但是讀取時會報錯 ImportError: cannot import name 'getuid' from 'os' (D:\anaconda\lib\os.py)

# pip
pip install feather-format
# 依賴會安裝:pyarrow-5.0.0-cp38-cp38-win_amd64.whl

# conda
conda install -c conda-forgefeather-format # 測試報錯

2.測試資料集

構建一個 5 列、1000 萬行隨機數。

import feather
import pandas as pd
import numpy as np

import os
os.chdir(r'C:\Users\111\Desktop')

np.random.seed = 2021
df_size = 10000000

df = pd.DataFrame({
    'a': np.random.rand(df_size),
    'b': np.random.rand(df_size),
    'c': np.random.rand(df_size),
    'd': np.random.rand(df_size),
    'e': np.random.rand(df_size)
    })
df.head()
'''
          a         b         c         d         e
0  0.515694  0.879751  0.346675  0.998066  0.647965
1  0.648172  0.044250  0.546985  0.668001  0.460173
2  0.774530  0.354780  0.034965  0.259252  0.037479
3  0.843657  0.956277  0.059882  0.394459  0.088319
4  0.263218  0.409887  0.149357  0.971544  0.657425
'''

3.pandas操作方式

  • 儲存

可以直接利用 DataFrame.to_feather() 進行儲存。使用語法為:

df.to_feather(path, compression, compression_level)
# -- path:檔案路徑
# -- compression:是否壓縮以及如何壓縮,支援(zstd/uncompressde/lz4)三種方式
# -- compression_level:壓縮水平(lz4不支援該引數)

df.to_feather('data.feather')
  • 載入
df = pd.read_feather('data.feather')

4.feather操作方式

原生 feather 方式與 pandas 操作方式類似,速度也差不多。

  • 儲存
feather.write_dataframe(df, 'data2.feather')
  • 載入
df = feather.read_dataframe('data2.feather')

5.csv VS feather

  • 寫入速度對比
# 匯入時間模組
import time

# 1.傳統csv方式
start = time.time()
df.to_csv('data_csv.csv')
end = time.time()
print('CSV Running time: %s Seconds' % (end-start))

# 2.原生feather
start = time.time()
feather.write_dataframe(df, 'data_feather_ys.feather')
end = time.time()
print('YS-feather Running time: %s Seconds' % (end-start))

# 3.pandas-feather
start = time.time()
df.to_feather('data_feather_pd.feather')
end = time.time()
print('Pd-feather Running time: %s Seconds' % (end-start))
'''
CSV Running time: 93.85435080528259 Seconds
YS-feather Running time: 0.3590412139892578 Seconds
Pd-feather Running time: 4.7694432735443115 Seconds
'''
  • 讀取速度對比
# 匯入時間模組
import time

# 1.傳統csv方式
start = time.time()
df1 = pd.read_csv('data_csv.csv')
end = time.time()
print('CSV Running time: %s Seconds' % (end-start))

# 2.原生feather
start = time.time()
df2 = feather.read_dataframe('data_feather_ys.feather')
end = time.time()
print('YS-feather Running time: %s Seconds' % (end-start))

# 3.pandas-feather
start = time.time()
df3 = pd.read_feather('data_feather_pd.feather')
end = time.time()
print('Pd-feather Running time: %s Seconds' % (end-start))

'''
CSV Running time: 11.32979965209961 Seconds
YS-feather Running time: 0.34105563163757324 Seconds
Pd-feather Running time: 0.45678043365478516 Seconds
'''
  • 檔案大小對比
# 肉眼對比
data_csv.csv             -- 0.97G
data_feather_ys.feather  -- 381M
data_feather_pd.feather  -- 381M

# 利用os獲取檔案大小(單位:MB)
import os
def get_FileSize(filePath):
    filePath = str(filePath)
    fsize = os.path.getsize(filePath)
    fsize = fsize / float(1024 * 1024)
    return round(fsize, 2)

print(get_FileSize('data_feather_ys.feather'))
print(get_FileSize('data_feather_pd.feather'))
print(get_FileSize('data_csv.csv'))
381.57 MB
381.57 MB
1003.63 MB

# 計算壓縮率
standart_ratio = os.stat('data_feather_ys.feather').st_size / os.stat('data_csv.csv').st_size
print(f'Standart feather compression ratio is {standart_ratio*100 :.1f}%')
# Standart feather compression ratio is 38.0%

四、總結

Feather 相比 csv 格式擁有明顯的效能提升。

  • 適合中型資料(GB為單位的資料),比如4GB的csv檔案,可能只佔用700M的feather檔案空間
  • 讀寫速度遠勝csv,而且相比較於資料庫又具有便攜的優勢,可以作為很好的中間媒介來傳輸資料
  • 類似於csv,feather也支援從原始檔中僅讀取所需要的列,可以減少記憶體的使用
df = pd.read_feather(path='data.feather', columns=["a","b","c"])

Parquet 是一種追求更多的壓縮空間的資料格式,也可以考慮替代 csv 格式。

參考連結:再見 CSV,速度提升 150 倍!

參考連結python讀feather格式檔案

參考連結:feather——高效能的python資料讀寫

參考連結:輕如“鴻毛(Feather)”的檔案格式卻重於泰山