我正在构建一个从 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);\nRun 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\nRun 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 添加行。然而,如何高效地构建一个呢?我可以创建一个,然后从 中创建一个,但这听起来像是最终会复制所有元素。有没有办法逐个元素构建,然后从这些元素构建一个?VecSeriesSeriesVecSeriesVecSeriesDataFrame
实际上,我将使用 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