arrow是apache開發的一種高壓縮的數據結構,發現用來存儲K線還是很不錯的選擇。
測試用python讀寫很方便,關鍵是足夠小,A股1支票1分鐘的數據,1個月大約是140多K吧。
結果從數據庫取出來存入arrow中,再用C++進行讀取,發現總有8小時的時差問題,估計就是東八區的問題。
c++讀取arrow數據,時間默認是按格林尼治時間來讀取,然后存入進去的沒有帶時區信息,因此讀,比如數據是2024年5月15日9點31分,存入應先將其轉成格林時間,即減掉8小時,即2024年5月15日1點31分,然后再消除時區印跡(貌似有時間印記c++讀取時會出錯),這樣C++那邊讀取的時間才能夠和這里寫入的時間對得上。
好,總結一下時間轉換,df中的時間一般從數據庫中讀取或是csv中讀取默認都沒有時間印記,但因為我們是在中國,所有人都認為看到的時間為東八區,因此存入arrow前先做時區調整,將之本地化東八區,然后轉成格林時間,再消除時間印記,存入arrow中,這樣所有人從arrow中讀取的時間都是格林時間,互相就對得上了。
demo示例:
讀取csv數據,注意,由于已經解析了時間格式,因此不需要再額外進行時間轉換:
df['time'] = pd.to_datetime(df['time'])??# 一般都是要做時間轉換的,但這時已經通過parse_dates已經成功解析了時間成為了datetime64[ns]這樣的類型
def read_csv(file_name):# 定義列名列表columns = ["time", "open"]data_types = {'open': 'float64'}# 讀取 CSV 文件,指定列名df_read = pd.read_csv(file_name, names=columns, dtype=data_types, header=None, parse_dates=["time"])# 打印讀取后的 DataFrameprint(df_read)return df_read
寫入arrow:
def write_arrow(df: DataFrame, file_name):import pyarrow as paimport pyarrow.parquet as pqif not df['time'].dt.tz:pd.to_datetime(df['time']).dt.tz_localize('Asia/Shanghai').dt.tz_convert('UTC').dt.tz_localize(None)table = pa.Table.from_pandas(df, preserve_index=False)pq.write_table(table, file_name)
if not df['time'].dt.tz: 表達的為如果沒有時區印記,即沒帶上時區信息,就先默認為東八區的時間本地化,再將之轉換為格林時間,最后將時區印記抹除(抹除的原因是防止C++讀取時出錯)
至于C++如何讀取這一塊,是有一點復雜,稍后有時間再補充上來。