我的问题可能可以被描述为对Rust和Polars来说都是非常新的。对我宽容点。:)
我尝试使用自定义函数建立一个模式,基于以下文档:https://pola-rs.github.io/polars-book/user-guide/dsl/custom_functions.html,但到目前为止我不成功。
在我的代码中,我有一个函数声明如下:
pub fn convert_str_to_tb(value: &str) -> f64 {
let value = value.replace(",", "");
let mut parts = value.split_whitespace();
let num = parts.next().unwrap().parse::<f64>().unwrap();
let unit = parts.next().unwrap();
match unit {
"KB" => num / (1000.0 * 1000.0 * 1000.0),
"MB" => num / (1000.0 * 1000.0),
"GB" => num / 1000.0,
"TB" => num,
_ => panic!("Unsupported unit: {}", unit),
}
}
我相信我应该可以这样调用这个函数:
df.with_columns([
col("value").map(|s| Ok(convert_str_to_tb(s))).alias("value_tb");
])
我的第一个问题是with_columns方法似乎不存在-我必须使用with_column。如果我使用with_column,我会收到以下错误:
the trait bound `Expr: IntoSeries` is not satisfied
the following other types implement trait `IntoSeries`:
Arc<(dyn polars::prelude::SeriesTrait + 'static)>
ChunkedArray<T>
Logical<DateType, Int32Type>
Logical<DatetimeType, Int64Type>
Logical<DurationType, Int64Type>
Logical<TimeType, Int64Type>
polars::prelude::SeriesrustcClick for full compiler diagnostic
我尝试转换的DataFrame:
let mut df = df!("volume" => &["volume01", "volume02", "volume03"],
"value" => &["1,000 GB", "2,000,000 MB", "3 TB"]).unwrap();
也许有一种方法可以在没有自定义函数的情况下做到这一点?
1条答案
按热度按时间7eumitmz1#
问题1,with_columns
关于文档,有一个令人困惑的注意事项--示例中的
df
是一个惰性 Dataframe 。您可以在使用自定义函数的完整代码片段中看到它们调用.lazy()
。.with_columns()
是惰性 Dataframe 上的可用方法。问题二,自定义函数
在自定义函数中预期的内容和您定义的内容之间存在一些类型问题。您期望输入str并输出f64。然而,由于错误意味着
s
参数实际上是Series
,并且期望返回值是Option<Series>
。这是怎么回事
.map()
函数为您提供了自定义函数需要迭代的序列。更新您的自定义函数以具有适当的arg和返回类型:
并称之为利用
给出输出: