我正在构建一个从 Raku NativeCall 到 Rust Polars 的接口,以获得很酷的 Arrow2 性能提升。在高层,我想使用 Polars 结构(例如 DataFrame 和 Series)作为匹配容器的属性。所以df.column
我想要这样的东西......
use polars::prelude::*;//{CsvReader, DataType, Field, Schema, DataFrame,};
use polars::prelude::{Result as PolarResult};
use polars::frame::DataFrame;
use polars::datatypes::DataType;
pub struct DataFrameC {
df: DataFrame,
}
impl DataFrameC {
fn new() -> DataFrameC {
DataFrameC {
df: DataFrame::default(),
}
}
fn column(&self, string: String) -> Series {
//let colin = self.df.column(&string).unwrap().head(Some(23));
let colin = self.df.column(&string).unwrap()
println!{"{}", colin};
colin
}
}
Run Code Online (Sandbox Code Playgroud)
(系列的类似方法 - 因此完成此 fn 的下一步是创建 aSeries::new()
然后se.set(colin) …
我有以下代码来查找数据框中年龄的平均值。
\nlet df = df! [\n "name" => ["panda", "polarbear", "seahorse"],\n "age" => [5, 7, 1],\n].unwrap();\n\nlet mean = df\n .lazy()\n .select([col("age").mean()])\n .collect().unwrap();\n\nprintln!("{:?}", mean);\n
Run Code Online (Sandbox Code Playgroud)\n找到平均值后,我想将值提取为f64
.
\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 age \xe2\x94\x82\n\xe2\x94\x82 --- \xe2\x94\x82\n\xe2\x94\x82 f64 \xe2\x94\x82 -----> how to transform into a single f64 of value 4.333333?\n\xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1\n\xe2\x94\x82 4.333333 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n通常,我会做类似df[0,0]
提取唯一值的事情。然而,由于 Polars 并不是索引的大力支持者,那么如何使用 Rust Polars 来做到这一点呢?
我正在尝试迭代 Polars rust 数据帧的每一行。
在这一努力中,我发现df.get
但文档说这很慢。然后我尝试过df.column("col").get
,但这似乎会带来类似的问题。
处理数据帧每一行的正确方法是什么?我需要将其上传到数据库并将其转换为结构。
我正在 Rust 中为 Polars 编写一个外部库(供Raku::Dan使用),并且想通过调用 df.lazy() 为 LazyFrame 对象获取一个不透明容器。
use polars::prelude::*;//{CsvReader, DataType, DataFrame, Series};
use polars::prelude::{Result as PolarResult};
use polars_lazy::prelude::*;
// LazyFrame Container
pub struct LazyFrameC {
lf: LazyFrame,
}
impl LazyFrameC {
fn new(ptr: *mut DataFrameC) -> LazyFrameC {
LazyFrameC {
lf: (*ptr).df.lazy(),
}
}
}
// extern functions for LazyFrame Container
#[no_mangle]
pub extern "C" fn lf_new(ptr: *mut DataFrameC) -> *mut LazyFrameC {
let df_c = unsafe {
assert!(!ptr.is_null());
&mut *ptr
};
Box::into_raw(Box::new(LazyFrameC::new(ptr)))
}
Run Code Online (Sandbox Code Playgroud)
不起作用,给出错误:
error[E0599]: …
Run Code Online (Sandbox Code Playgroud) 我想DataFrame
使用 Rust 创建一个大型 Polars,使用从网页上抓取的数据逐行构建它。什么是有效的方法来做到这一点?
看起来应该从ofDataFrame
创建而不是向空 DataFrame 添加行。然而,如何高效地构建一个呢?我可以创建一个,然后从 中创建一个,但这听起来像是最终会复制所有元素。有没有办法逐个元素构建,然后从这些元素构建一个?Vec
Series
Series
Vec
Series
Vec
Series
DataFrame
实际上,我将使用 Rayon 并行构建多个 DataFrame,然后将它们组合起来,但看起来 vstack 可以满足我的要求。这是单个数据帧的创建,我不知道如何有效地完成。
我确实查看了 CSV 解析器的源代码,但这非常复杂,并且可能高度优化,但是是否有一种简单的方法仍然相当有效?
我正在 wasm 环境中使用 Polars。
我注意到 LazyFrame.collect 操作不一致,在处理某些数据集时有时会创建线程。
这是与该问题相关的代码
#[wasm_bindgen]
pub fn start(buff: &[u8],
item_id:&str,
order_id:&str,
item_name:&str) -> JsValue{
let cursor = Cursor::new(buff);
let lf = CsvReader::new(cursor).with_ignore_parser_errors(true).finish().unwrap().lazy();
let df = lf.groupby([col(order_id)]);
let df = df.agg([col(item_id),col(item_name)]);
// Error occurs here
let df = df.collect().unwrap();
}
Run Code Online (Sandbox Code Playgroud)
使用特定数据集给我带来了错误:
panicked at 'failed to spawn thread: Error { kind: Unsupported, message: "operation not supported on this platform" }'
Run Code Online (Sandbox Code Playgroud)
因为它正在尝试在 WASM 环境中生成线程。
然而,对于其他数据集,这个过程将完美执行。并且它不会尝试创建线程。由于使用各种数据集进行测试,问题似乎不是文件大小。
我想知道 Lazyframe.collect 操作的哪一部分会造成这种不一致以及如何避免它。
工作.csv
Order ID,Product ID,Product Name
InvoiceNo0,Product ID0,Product Name0
InvoiceNo0,Product ID1,Product Name1 …
Run Code Online (Sandbox Code Playgroud) 假设我有一个像这样的结构向量:
struct Test {
id:u32,
amount:u32
}
fn main() {
let test_vec:Vec<Test> = vec![Test{id:1,amount:3}, Test{id:3,amount:4}];
}
Run Code Online (Sandbox Code Playgroud)
有没有办法将其放入极坐标数据框中,其中列名称是结构字段?
希望得到如下输出:
id amount
0 1 3
1 3 4
Run Code Online (Sandbox Code Playgroud) 我在使用 Polars 版本 0.37.0 并运行 Cargo Clippy 进行代码检查时遇到问题。该错误出现在 Polars-arrow-0.37.0 箱中,特别是 utf8_to.rs 文件中。以下是详细的错误消息:
error[E0308]: `if` and `else` have incompatible types
--> /Users/me/.cargo/registry/src/index.crates.io-6f17d22bba15001f/polars-arrow-0.37.0/src/compute/cast/utf8_to.rs:101:9
|
98 | let buffers = if uses_buffer {
| ___________________-
99 | | Arc::from([arr.values().clone()])
| | --------------------------------- expected because of this
100 | | } else {
101 | | Arc::from([])
| | ^^^^^^^^^^^^^ expected an array with a fixed size of 1 element, found one with 0 elements
102 | | };
| |_____- `if` and `else` …
Run Code Online (Sandbox Code Playgroud) 我需要在 Polars_lazy 中编写自己的表达式。根据我对源代码的理解,我需要编写一个返回 Expr::Function 的函数。问题是为了构造这种类型的对象,必须提供 FunctionOptions 类型的对象。需要注意的是,这个类是公共的,但成员是 pub(crate) 的,因此在 create 之外无法构造这样的对象。有办法解决这个问题吗?
正如这里所述,Polars 为 LazyFrames 引入了自动缓存机制,该机制在逻辑计划中多次出现,因此用户不必主动执行缓存。
然而,在尝试检查他们的新机制时,我遇到了自动缓存未最佳执行的情况:
没有显式缓存:
import polars as pl
df1 = pl.DataFrame({'id': [0,5,6]}).lazy()
df2 = pl.DataFrame({'id': [0,8,6]}).lazy()
df3 = pl.DataFrame({'id': [7,8,6]}).lazy()
df4 = df1.join(df2, on='id')
print(pl.concat([df4.join(df3, on='id'), df1,
df4]).explain())
Run Code Online (Sandbox Code Playgroud)
我们得到了逻辑计划:
UNION
PLAN 0:
INNER JOIN:
LEFT PLAN ON: [col("id")]
INNER JOIN:
LEFT PLAN ON: [col("id")]
CACHE[id: a4bcf9591fefc837, count: 3]
DF ["id"]; PROJECT 1/1 COLUMNS; SELECTION: "None"
RIGHT PLAN ON: [col("id")]
CACHE[id: 8cee8e3a6f454983, count: 1]
DF ["id"]; PROJECT 1/1 COLUMNS; SELECTION: "None"
END INNER JOIN
RIGHT PLAN ON: …
Run Code Online (Sandbox Code Playgroud) rust-polars ×10
rust ×9
dataframe ×2
raku ×2
data-science ×1
python ×1
rayon ×1
struct ×1
webassembly ×1