Rust: polars行遍历,从dataframe到struct及Bar设计比较

pandas提供了iterrows()、itertuples()、apply等行遍历的方式,还是比较方便的。
polars的列操作功能非常强大,这个在其官网上有详细的介绍。由于polars底层的arrow是列存储模式,行操作效率低下,官方也不推荐以行方式进行数据操作。但是还是有部分场景可能会用到行遍历的情况。

polars如何进行行遍历,今天尝试一下非apply的方式。

场景:polars读取相应的关于历史股价的csv文件,其中有基本的行情信息,那么,如何对读取到的文件进行快速的行遍历?这种场景在行情驱动的策略回测中比较常见。

在这里插入图片描述一、初步方案:

1、总体方案

1、csv => dataframe 
2、dataframe =>into_struct ,得到structchunked
3、struchchunked =>在bars进行行遍历。

2、Bar类型
至于Bar类型的设计,存在两种方案:

(1)值类型的Bar

#[warn(dead_code)]
struct Bar{code:String,date:String,open:f32,high:f32,close:f32,low:f32,volume:f32,amount:f32,is_fq:bool,
}

(2)有引用类型的Bar

#[warn(dead_code)]
struct Bar2<'a>{code:&'a str,date:&'a str,open:f32,high:f32,close:f32,low:f32,volume:f32,amount:f32,is_fq:bool,
}

二、toml

注意,polars对features的设置要求高,有些用到的特性需要准确打开,否则代码编译会通不过。这一点在polars文档中经常没有写清楚,也算是一个坑。

[package]
name = "my_duckdb"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
polars = { version = "*", features = ["lazy","dtype-struct"] }

注意,features中,一定要加上"dtype-struct"。

三、main.rs

根据上面的设计,全部代码如下:

use polars::prelude::*;
use std::time::Instant;#[warn(dead_code)]
struct Bar{code:String,date:String,open:f32,high:f32,close:f32,low:f32,volume:f32,amount:f32,is_fq:bool,
}
#[warn(dead_code)]
struct Bar2<'a>{code:&'a str,date:&'a str,open:f32,high:f32,close:f32,low:f32,volume:f32,amount:f32,is_fq:bool,
}
fn main() {let time0 = Instant::now();// test2.csv:64w行let csv = "test2.csv"; let df = polars_lazy_read_csv(csv);println!("read raw csv cost time : {:?} seconds",time0.elapsed().as_secs_f32());let time1 = Instant::now();let rows = df.into_struct("bars");println!("dataframe => structs cost time : {:?} seconds",time1.elapsed().as_secs_f32());let time2 = Instant::now();let bars = get_vec_bars(&rows);println!("dataframe => bars cost time : {:?} seconds",time2.elapsed().as_secs_f32());let time3 = Instant::now();let bar2s = get_vec_bar2s(&rows);println!("dataframe => bar2s cost time : {:?} seconds",time3.elapsed().as_secs_f32());println!("bars length :{:?}",bars.len());println!("bar2s length:{:?}",bar2s.len());
}fn get_bar(row:&[AnyValue])->Bar{let code = row.get(0).unwrap();let mut new_code = "";if let &AnyValue::Utf8(value) = code{new_code = value;}let mut new_date = ""; let date = row.get(1).unwrap();if let &AnyValue::Utf8(v) = date {new_date = v;}let open =row[2].extract::<f32>().unwrap();let high:f32 = row[3].extract::<f32>().unwrap();let close =row[4].extract::<f32>().unwrap();let low:f32 = row[5].extract::<f32>().unwrap();let volume =row[6].extract::<f32>().unwrap();let amount:f32 = row[7].extract::<f32>().unwrap();let mut is_fq = false;if let &AnyValue::Boolean(b) = row.get(8).unwrap(){is_fq = b;}let bar = Bar{code: String::from(new_code),date: String::from(new_date),open:open,high:high,close:close,low:low,volume:volume,amount,is_fq:is_fq,};bar
}fn get_bar2<'a>(row:&'a [AnyValue])->Bar2<'a>{let code = row.get(0).unwrap();let mut new_code = "";if let &AnyValue::Utf8(value) = code{new_code = value;}let mut new_date = ""; let date = row.get(1).unwrap();if let &AnyValue::Utf8(v) = date {new_date = v;}let open =row[2].extract::<f32>().unwrap();let high:f32 = row[3].extract::<f32>().unwrap();let close =row[4].extract::<f32>().unwrap();let low:f32 = row[5].extract::<f32>().unwrap();let volume =row[6].extract::<f32>().unwrap();let amount:f32 = row[7].extract::<f32>().unwrap();let mut is_fq = false;if let &AnyValue::Boolean(b) = row.get(8).unwrap(){is_fq = b;}let bar = Bar2{code: new_code,date: new_date,open:open,high:high,close:close,low:low,volume:volume,amount,is_fq:is_fq,};bar
}
fn get_vec_bars(data: &StructChunked)-> Vec<Bar>{let mut bars = Vec::new();for row in data{let bar = get_bar(row);bars.push(bar);}bars
}fn get_vec_bar2s(data: &StructChunked)-> Vec<Bar2>{let mut bars = Vec::new();for row in data{let bar = get_bar2(row);bars.push(bar);}bars
}
fn polars_lazy_read_csv(filepath:&str) ->DataFrame{let polars_lazy_csv_time  = Instant::now();let p = LazyCsvReader::new(filepath).has_header(true).finish().unwrap();let mut df = p.collect().expect("error to dataframe!");println!("polars lazy 读出csv的行和列数:{:?}",df.shape());println!("polars lazy 读csv 花时: {:?} 秒!", polars_lazy_csv_time.elapsed().as_secs_f32());df
}

四、输出与比较
对于一个64万行,9列的csv文件,需要遍历转换Vec< Bar >类型,
1、输出如下:

polars lazy 读出csv的行和列数:(640710, 9)
polars lazy 读csv 花时: 0.058484446 秒!
read raw csv cost time : 0.058487203 seconds
dataframe => structs cost time : 2.8842e-5 seconds
dataframe => bars cost time : 0.131985 seconds
dataframe => bar2s cost time : 0.10357016 seconds
bars length :640710
bar2s length:640710

总体上看,从dataframe到struct这层,效率比较高,主要的时间花在了structchunked至bars这部分上面。

2、值类型Bar和引用类型Bar

从输出结果,可以看出,引用类型的Bar的效率要高一些,提效了20%。因为减少了堆分配所需要的时间。

五、其它

polars目前还没有发现有类似pandas的行遍历的方式,后面将持续跟踪。
此外,dataframe转bars的效率并不高,期待找到更高效的方式替代。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/366907.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过shell脚本创建MySQl数据库

通过shell脚本创建数据库 #!/bin/bashserverIP10.1.1.196 SERVER_NAMEecho $serverIP | cut -d . -f4cat<<EOF>db.sql drop database if exists ${SERVER_NAME}_scheduler; drop database if exists ${SERVER_NAME}_kms; drop database if exists ${SERVER_NAME}_uim…

修改CentOS7 yum源

修改CentOS默认yum源为阿里镜像源 备份系统自带yum源配置文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 下载ailiyun的yum源配置文件 CentOS7 yum源如下&#xff1a; wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun…

【0299】Postgres内核之哈希表(Hash Tables)

0. 哈希表(Hash Tables) 哈希表是 一种用于存储键值对的数据结构。与使用索引号访问元素的基本数组不同,哈希表使用键来查找表条目。这使得数据管理对于用户来说更易于管理,因为按属性对数据条目进行分类比按它们在一个巨大的列表中的数量更容易。 在 C++ 中,我们将哈希…

单向链表结构

链表结构简介 链表结构是一种用比较特殊的数据结构类型&#xff0c;它也是线性数据结构中的一种&#xff0c;但是与栈结构等线性数据结构不同&#xff0c;它的内部结构并不是一个简单的存储空间&#xff0c;而是一个带有指向性质的单元。要理解链表结构要弄清楚两个问题&#x…

鸿蒙:路由Router原理

页面路由&#xff1a;在应用程序中实现不同页面之间的跳转和数据传递 典型应用&#xff1a;商品信息返回、订单等多页面跳转 页面栈最大容量为32个页面&#xff0c;当页面需要销毁可以使用router.clear()方法清空页面栈 router有两种页面跳转模式&#xff1a; router.pushUrl…

入门Axure:快速掌握原型设计技能

2002 年&#xff0c;维克托和马丁在旧金山湾区的一家初创公司工作&#xff0c;发现自己一再被软件开发生命周期的限制所困扰&#xff0c;而且产品团队在编写规范之前很难评估他们的解决方案&#xff0c;开发人员经常不理解&#xff08;或不阅读&#xff09;给出的规范&#xff…

线程池666666

1. 作用 线程池内部维护了多个工作线程&#xff0c;每个工作线程都会去任务队列中拿取任务并执行&#xff0c;当执行完一个任务后不是马上销毁&#xff0c;而是继续保留执行其它任务。显然&#xff0c;线程池提高了多线程的复用率&#xff0c;减少了创建和销毁线程的时间。 2…

如何指定Microsoft Print To PDF的输出路径

在上一篇文章中&#xff0c;介绍了三种将文件转换为PDF的方式。默认情况下&#xff0c;在Microsoft Print To PDF的首选项里&#xff0c;是看不到输出路径的设置的。 需要一点小小的手段。 运行输入 control 打开控制面板&#xff0c;选择硬件和声音下的查看设备和打印机 找到…

ardupilot开发 --- 坐标变换 篇

Good Morning, and in case I dont see you, good afternoon, good evening, and good night! 0. 一些概念1. 坐标系的旋转1.1 轴角法1.2 四元素1.3 基于欧拉角的旋转矩阵1.3.1 单轴旋转矩阵1.3.2 多轴旋转矩阵1.3.3 其他 2. 齐次变换矩阵3. visp实践 0. 一些概念 相关概念&am…

github仓库的基本使用-创建、上传文件、删除

1.第一步 先点击左侧菜单栏的远程仓库 2.点击NEW 3.创建仓库 然后点击右下角的 CREATE 4.点击code 点击SSH,然后我出现了You don’t have any public SSH keys in your GitHub account. You can add a new public key, or try cloning this repository via HTTPS. 1&#xff…

你喜欢波段交易吗?

波段交易的核心在于精准捕捉市场中的长期趋势波动&#xff0c;以实现更为稳健的收益。与剥头皮和日内交易不同&#xff0c;波段交易者更倾向于持有交易头寸数日乃至数周&#xff0c;以更宽广的视角把握市场动态。 这种交易方式的优势在于&#xff0c;它降低了对即时市场反应的…

JavaWeb系列三: JavaScript学习 下

文章目录 js数组定义方式数组遍历 js函数函数入门函数使用方式使用方式一使用方式二 函数注意事项函数练习题 定义对象使用object定义使用{}定义 事件onload事件onclick事件失去焦点事件内容发生改变事件表单提交事件静态注册动态注册表单作业 dom对象文档对象模型document对象…

Linux --账号和权限管理

目录 1、 管理用户账号和组账概述 1.1 用户账号分类 1.2 组账号 1.3 UID 和 GID 2、用户账号文件 2.1 passwd 2.2 shadow 3、管理目录和文件属性 3.1 chage 命令 3.2 useradd 命令 3.3 passwd 命令 ​编辑3.4 usermod 命令 3.5 userdel 命令 4、用户账户的初始配置…

爬数据是什么意思?

爬数据的意思是&#xff1a;通过网络爬虫程序来获取需要的网站上的内容信息&#xff0c;比如文字、视频、图片等数据。网络爬虫&#xff08;网页蜘蛛&#xff09;是一种按照一定的规则&#xff0c;自动的抓取万维网信息的程序或者脚本。 学习一些爬数据的知识有什么用呢&#x…

分解+降维+预测!多重创新!直接写核心!EMD-KPCA-Transformer多变量时间序列光伏功率预测

分解降维预测&#xff01;多重创新&#xff01;直接写核心&#xff01;EMD-KPCA-Transformer多变量时间序列光伏功率预测 目录 分解降维预测&#xff01;多重创新&#xff01;直接写核心&#xff01;EMD-KPCA-Transformer多变量时间序列光伏功率预测效果一览基本介绍程序设计参…

[数据集][目标检测]水面垃圾水面漂浮物检测数据集VOC+YOLO格式3749张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;3749 标注数量(xml文件个数)&#xff1a;3749 标注数量(txt文件个数)&#xff1a;3749 标注…

聊聊etsy平台,一个年入百万的项目

聊聊etsy平台&#xff0c;一个年入百万的项目 什么是etsy,这是怎样一个平台&#xff0c;怎样盈利的&#xff1f;相信现在大家满脑子都是这些疑问。 这个平台也是无意间一个学员提到的&#xff0c;据说他朋友靠这个平台年赚好几百万。苦于门槛太高&#xff0c;他也做不了。今天…

web权限到系统权限 内网学习第一天 权限提升 使用手工还是cs???msf可以不??

现在开始学习内网的相关的知识了&#xff0c;我们在拿下web权限过后&#xff0c;我们要看自己拿下的是什么权限&#xff0c;可能是普通的用户权限&#xff0c;这个连添加用户都不可以&#xff0c;这个时候我们就要进行权限提升操作了。 权限提升这点与我们后门进行内网渗透是乘…

ATFX汇市:欧元区CPI与失业率数据同时发布,欧元或迎剧烈波动

ATFX汇市&#xff1a;CPI数据是中央银行决策货币政策的主要依据&#xff0c;失业率数据是中央银行判断劳动力市场健康状况的核心指标。欧元区的CPI和失业率数据将在今日17:00同时发布&#xff0c;在欧央行6月6日降息一次的背景下&#xff0c;两项数据将显著影响国际市场对欧央行…

问题-小技巧-Win11的常用快捷方式和有用快捷方式

文章目录 常用快捷方式1、CtrlA 全部选中2、Ctrl Z 撤销3、Ctrl X 剪切4、Ctrl C 粘贴5、Ctrl V 复制6、winshifts截图&#xff0c;Windows系统自带截图工具&#xff0c;功能太少7、ctrlshifts截图&#xff0c;edge自带截图工具&#xff0c;使用时需要打开edge8、 winv 可以查看…