假设我想在数据框中添加一个数组列。通过在构造时指定模式,可以在 python 实现中轻松完成此操作。这是一些代码来展示我的问题
fn main() {
let ArrayType = DataType::Array(Box::new(DataType::Array(Box::new(DataType::Int64, 2), 2)
let mut s1 = Series::new_empty("test".into(), &ArrayType);
...
// I can't add data to this array
let test_data = Array2::from_shape_vec((2,2), vec![1,2,3,4]).unwrap();
// this can't be added directly, so I tried iterating over it and using list builders
// but i must be doing something wrong
}
看起来我需要使用分块数组生成器,但我无法找到使用数组执行此操作的正确语法。我可以构造一个列表列表,但我想利用数组数据类型的强制大小调整。
我尝试过列出原始块构建器
let mut builder = ListPrimitiveChunkedBuilder::new(name, capacity, values_capacity, inner_type);
但是以这种方式构造的元素不能被推入具有数组数据类型的系列中。缺少有关如何将列表或数组添加到系列、列或数据帧中的文档。
这篇文章非常无益,因为答案是“你不能用 Rust 做到这一点”。如果是这种情况,那么为什么官方文档建议你应该能够在 Rust 中做到这一点。也没有关于为什么尚未实施的问题。
正如其他链接问题中所述,数组生成器不安全且不公开。相反,ListPrimitiveChunkedBuilder 是公共的,可以轻松转换为 Array。正如我在另一个问题中所说,这样做确实感觉很愚蠢,但仍然可以做到。
您还询问了如何发展您的系列。您可以通过以相同的方式创建另一个系列并像这样附加来完成此操作:
fn main() {
let mut col1: ListPrimitiveChunkedBuilder<Float64Type> =
ListPrimitiveChunkedBuilder::new("array".into(), 3, 6, DataType::Float64);
col1.append_slice(&[1.1, 2.2]);
col1.append_slice(&[2.1, 2.2]);
col1.append_slice(&[3.1, 2.2]);
let mut s = col1
.finish()
.into_series()
.cast(&DataType::Array(Box::new(DataType::Float64), 2))
.unwrap();
let mut col2: ListPrimitiveChunkedBuilder<Float64Type> =
ListPrimitiveChunkedBuilder::new("array".into(), 3, 6, DataType::Float64);
col2.append_slice(&[2.1, 3.2]);
col2.append_slice(&[4.1, 5.2]);
col2.append_slice(&[6.1, 7.2]);
let s2 = col2
.finish()
.into_series()
.cast(&DataType::Array(Box::new(DataType::Float64), 2))
.unwrap();
s.append(&s2).unwrap();
eprintln!("series has {} chunks", s.n_chunks());
// rechunking is optional here but every time you append,
// it's non-contiguous in memory and rechunk puts it contiguous again.
let s = s.rechunk();
eprintln!("{}", s)
}
结果:
series has 2 chunks
shape: (6,)
Series: 'array' [array[f64, 2]]
[
[1.1, 2.2]
[2.1, 2.2]
[3.1, 2.2]
[2.1, 3.2]
[4.1, 5.2]
[6.1, 7.2]
]