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++如何读取这一块,是有一点复杂,稍后有时间再补充上来。