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.mzph.cn/diannao/39581.shtml

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

相关文章

react_后台管理_项目

目录 1.运行项目 2. 项目结构 ①项目顶部导航栏 ②项目左侧导航栏 ③主页面-路由切换区 本项目使用的是 reacttsscss 技术栈。 1.运行项目 在当前页面顶部下载本项目&#xff0c;解压后使用编辑器打开&#xff0c;然后再终端输入命令&#xff1a; npm i 下载依赖后&am…

【应急响应】Windows应急响应 - 基础命令篇

前言 在如今的数字化时代&#xff0c;Windows系统面对着越来越复杂的网络威胁和安全挑战。本文将深入探讨在Windows环境下的实战应急响应策略。我们将重点关注实际应急响应流程、关键工具的应用&#xff0c;以及如何快速准确地识别和应对安全事件。通过分享实际案例分析&#…

FIO压测磁盘性能以及需要注意的问题

一、压测类型 1、顺序读&#xff08;IO&#xff09;&#xff1a;read&#xff0c;bs1M&#xff0c;job数从1开始往上加&#xff1a;2、3、4... 2、顺序写&#xff08;IO&#xff09;&#xff1a;write&#xff0c;bs1M&#xff0c;job数从1开始往上加&#xff1a;2、3、4... …

如何通过 1688 商品详情的 API 接口获取商品的详细信息

在当今数字化商业的大背景下&#xff0c;能够从 1688 这样规模庞大且商品种类丰富的电商平台中准确、高效地获取商品的详细信息&#xff0c;对于众多企业和开发者而言&#xff0c;具有举足轻重的意义。而通过 1688 商品详情的 API 接口来实现这一目标&#xff0c;无疑是一种强大…

【ACM出版,马来西亚-吉隆坡举行】第四届互联网技术与教育信息化国际会议 (ITEI 2024)

作为全球科技创新大趋势的引领者&#xff0c;中国不断营造更加开放的科技创新环境&#xff0c;不断提升学术合作的深度和广度&#xff0c;构建惠及各方的创新共同体。这是对全球化的新贡献&#xff0c;是构建人类命运共同体的新贡献。 第四届互联网技术与教育信息化国际学术会议…

【 木兰宽松许可证】

木兰宽松许可证&#xff0c; 第1版 2019年8月 http://license.coscl.org.cn/MulanPSL 您对“软件”的复制、使用、修改及分发受木兰宽松许可证&#xff0c;第1版&#xff08;“本许可证”&#xff09;的如下条款的约束&#xff1a; 定义 “软件”是指由“贡献”构成的许可在“本…

【C++知识点总结全系列 (07)】:模板与泛型编程详细总结与分析

模板与泛型编程 1、概述(1)What&#xff08;什么是模板、泛型编程&#xff09;(2)Why(3)Which(4)模板参数A.WhatB.HowC.模板参数的类型成员D.默认模板参数 2、模板函数3、模板类(1)How&#xff08;如何定义和使用模板类&#xff09;(2)成员模板 4、模板实参推断(1)What&#xf…

入侵检测模型

入侵检测模型&#xff08;Intrusion Detection Model&#xff09;在网络安全中起着至关重要的作用。它们用于识别和响应未经授权的访问和攻击行为。以下是常见的入侵检测模型的详细介绍&#xff1a; 一、入侵检测模型分类 基于签名的入侵检测模型&#xff08;Signature-Based …

昇思25天学习打卡营第7天|Pix2Pix实现图像转换

文章目录 昇思MindSpore应用实践基于MindSpore的Pix2Pix图像转换1、Pix2Pix 概述2、U-Net架构定义UNet Skip Connection Block 2、生成器部分3、基于PatchGAN的判别器4、Pix2Pix的生成器和判别器初始化5、模型训练6、模型推理 Reference 昇思MindSpore应用实践 本系列文章主要…

大数据面试题之Flink(3)

如何确定Flink任务的合理并行度? Flink任务如何实现端到端一致? Flink如何处理背(反)压? Flink解决数据延迟的问题 Flink消费kafka分区的数据时flink件务并行度之间的关系 使用flink-client消费kafka数据还是使用flink-connector消费 如何动态修改Flink的配置&a…

实战:基于Java的大数据处理与分析平台

实战&#xff1a;基于Java的大数据处理与分析平台 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将探讨如何利用Java构建高效的大数据处理与分析平台。…

Python基础003

Python流程控制基础 1.条件语句 内置函数input a input("请输入一段内容&#xff1a;") print(a) print(type(a))代码执行的时候遇到input函数&#xff0c;就会等键盘输入结果&#xff0c;已回车为结束标志&#xff0c;也就时说输入回车后代码才会执行 2.顺序执行…

pandas数据分析(5)

pandas使用Numpy的np.nan代表缺失数据&#xff0c;显示为NaN。NaN是浮点数标准中地Not-a-Number。对于时间戳&#xff0c;则使用pd.NaT&#xff0c;而文本使用的是None。 首先构造一组数据&#xff1a; 使用None或者np.nan来表示缺失的值&#xff1a; 清理DataFrame时&#xf…

深度学习之交叉验证

交叉验证&#xff08;Cross-Validation&#xff09;是一种用于评估和验证机器学习模型性能的技术&#xff0c;尤其是在数据量有限的情况下。它通过将数据集分成多个子集&#xff0c;反复训练和测试模型&#xff0c;以更稳定和可靠地估计模型的泛化能力。常见的交叉验证方法有以…

java设计模式(四)——抽象工厂模式

一、模式介绍 改善在工厂方法模式中&#xff0c;扩展时新增产品类、工厂类&#xff0c;导致项目中类巨多的场面&#xff0c;减少系统的维护成本&#xff0c;且一个工厂可以生成多种产品&#xff0c;而不是同一种的产品&#xff0c;比如一个工厂既可以生产鞋子又可以衣服&#…

解决数据库PGSQL,在Mybatis中创建临时表报错TODO IDENTIFIER,连接池用的Druid。更换最新版本Druid仍然报错解决

Druid版本1.1.9报错Caused by: java.sql.SQLException: sql injection violation, syntax error: TODO IDENTIFIER : CREATE TEMPORARY TABLE temp_ball_classify (id int8 NOT NULL,create_time TIMESTAMP,create_by VARCHAR,classify_name VARCHAR) 代码如下&#xff1a; 测…

四川蔚澜时代电子商务有限公司打造抖音电商服务新高地

在数字化浪潮汹涌澎湃的今天&#xff0c;电商行业以其独特的魅力和强大的市场潜力&#xff0c;成为了推动经济增长的新引擎。四川蔚澜时代电子商务有限公司&#xff0c;作为这个领域的佼佼者&#xff0c;正以其专业的服务、创新的理念和卓越的实力&#xff0c;引领抖音电商服务…

用AI,每天创作200+优质内容,2分钟教会你操作!

前段时间发布了这篇“寻找爆款文案及标题的9大渠道&#xff0c;直接搬运都能搞流量&#xff01;”&#xff0c;里面我讲到如何寻找爆款标题。最近不少朋友问我&#xff0c;如何创作这个标题相关的内容。 多数平台都有风控规则&#xff0c;有些平台内容也会有字数要求。为了让大…

SpringBoot 项目整合 MyBatis 框架,附带测试示例

文章目录 一、创建 SpringBoot 项目二、添加 MyBatis 依赖三、项目结构和数据库表结构四、项目代码1、application.yml2、TestController3、TbUser4、TbUserMapper5、TestServiceImpl6、TestService7、TestApplication8、TbUserMapper.xml9、MyBatisTest 五、浏览器测试结果六、…

JavaScript实现时钟计时

会动的时钟 1.目标 2.分析 1.最开始页面不显示时间&#xff0c;有两个按钮 开始 暂停。开始按钮是可以点击的&#xff0c;暂停按钮不能点击 2.当点击开始按钮后&#xff0c;设置开始按钮不可用&#xff0c;暂停按钮可用。然后将当前系统时间放到按钮上面。每隔1秒中更新一下…