一、背景
日常使用 Python
讀取數據時一般都是 json
、csv
、txt
、xlsx
等格式,或者直接從數據庫讀取。
針對大數據量一般存儲為 csv
格式,但文件占用空間比較大,保存和加載速度也較慢。
而 feather
便是一種速度更快、更加輕量級(壓縮后)的二進制保存格式。
二、feather是什么?
Feather
是一種用於存儲數據幀的數據格式。
一句話描述:高速讀寫壓縮二進制文件。
Feather
其實是 Apache Arrow
項目中包含的一種數據格式,但是由於其優異的性能,該文件格式也被單獨打包,放在 pip
中進行安裝。
Pandas
也支持對 Feather
的讀寫操作。
最初是為了 Python
和 R
之間快速交互而設計的,初衷很簡單,就是盡可能高效地完成數據在內存中轉換的效率。
難能可貴的是,R
、Julia
、python
均可以解析 feather
,可以說是3種語言之間進行交互的強力工具了,讀寫速度一流。
現在 Feather
也不僅限於 Python
和 R
,基本每種主流的編程語言中都可以用 Feather
文件。
不過,它的數據格式並不是為長期存儲而設計的,僅限於一般的短期存儲。
-- 此處不好理解:長期?短期?如何界定?
-- 如果長期儲存,feather 的空間壓縮並不是最好的,可以了解下 Parquet。feather也可以長期存儲,只不過不是最優解。
三、使用方法
在 Python
中,可以通過 pandas
或 Feather
兩種方式進行操作。
但建議不要使用 pandas
自帶的 to_feather
和 read_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 倍!