方法收集

 
```
// src/data_deal.rs
use polars::prelude::*;
use std::path::Path;
use chrono::prelude::*;
use std::collections::HashMap;

/// 数据处理结构体,封装常用的 Polars 操作
pub struct DataDeal {
    df: Option<DataFrame>,
    lazy_df: Option<LazyFrame>,
}

impl DataDeal {
    /// 创建新的空 DataDeal 实例
    pub fn new() -> Self {
        Self {
            df: None,
            lazy_df: None,
        }
    }

    /// 从 DataFrame 创建实例
    pub fn from_dataframe(df: DataFrame) -> Self {
        Self {
            df: Some(df),
            lazy_df: None,
        }
    }

    /// 从惰性 DataFrame 创建实例
    pub fn from_lazyframe(lazy_df: LazyFrame) -> Self {
        Self {
            df: None,
            lazy_df: Some(lazy_df),
        }
    }

    // ==================== 数据创建方法 ====================

    /// 创建示例 DataFrame
    pub fn create_sample_data(&mut self) -> PolarsResult<&mut Self> {
        self.df = Some(df! [
            "id" => [1, 2, 3, 4, 5],
            "name" => ["Alice", "Bob", "Charlie", "David", "Eve"],
            "age" => [25, 30, 35, 40, 28],
            "department" => ["IT", "HR", "IT", "Finance", "HR"],
            "salary" => [50000.0, 45000.0, 60000.0, 55000.0, 48000.0],
            "join_date" => [
                NaiveDate::from_ymd_opt(2020, 1, 15).unwrap(),
                NaiveDate::from_ymd_opt(2019, 3, 20).unwrap(),
                NaiveDate::from_ymd_opt(2021, 6, 10).unwrap(),
                NaiveDate::from_ymd_opt(2018, 11, 5).unwrap(),
                NaiveDate::from_ymd_opt(2022, 2, 28).unwrap(),
            ],
        ]?);
        Ok(self)
    }

    /// 从 Vec 创建 DataFrame
    pub fn create_from_vectors(
        &mut self,
        columns: HashMap<&str, Vec<Series>>,
    ) -> PolarsResult<&mut Self> {
        let mut series_vec = Vec::new();
        for (name, series) in columns {
            for s in series {
                series_vec.push((name, s));
            }
        }
        self.df = Some(DataFrame::new(series_vec)?);
        Ok(self)
    }

    // ==================== 数据读取方法 ====================

    /// 读取 CSV 文件
    pub fn read_csv<P: AsRef<Path>>(&mut self, path: P) -> PolarsResult<&mut Self> {
        self.df = Some(LazyFrame::scan_csv(path, Default::default())?.collect()?);
        Ok(self)
    }

    /// 惰性读取 CSV 文件
    pub fn read_csv_lazy<P: AsRef<Path>>(&mut self, path: P) -> PolarsResult<&mut Self> {
        self.lazy_df = Some(LazyFrame::scan_csv(path, Default::default())?);
        Ok(self)
    }

    /// 读取 Parquet 文件
    pub fn read_parquet<P: AsRef<Path>>(&mut self, path: P) -> PolarsResult<&mut Self> {
        self.df = Some(LazyFrame::scan_parquet(path, Default::default())?.collect()?);
        Ok(self)
    }

    // ==================== 数据写入方法 ====================

    /// 写入 CSV 文件
    pub fn write_csv<P: AsRef<Path>>(&self, path: P) -> PolarsResult<()> {
        if let Some(ref df) = self.df {
            let mut file = std::fs::File::create(path)?;
            CsvWriter::new(&mut file).finish(df)?;
        } else if let Some(ref lazy_df) = self.lazy_df {
            let df = lazy_df.clone().collect()?;
            let mut file = std::fs::File::create(path)?;
            CsvWriter::new(&mut file).finish(&df)?;
        }
        Ok(())
    }

    /// 写入 Parquet 文件
    pub fn write_parquet<P: AsRef<Path>>(&self, path: P) -> PolarsResult<()> {
        if let Some(ref df) = self.df {
            let mut file = std::fs::File::create(path)?;
            ParquetWriter::new(&mut file).finish(df)?;
        } else if let Some(ref lazy_df) = self.lazy_df {
            let df = lazy_df.clone().collect()?;
            let mut file = std::fs::File::create(path)?;
            ParquetWriter::new(&mut file).finish(&df)?;
        }
        Ok(())
    }

    // ==================== 数据筛选和选择方法 ====================

    /// 筛选行
    pub fn filter(&mut self, condition: Expr) -> PolarsResult<&mut Self> {
        self.to_lazy();
        if let Some(ref lazy_df) = self.lazy_df {
            self.lazy_df = Some(lazy_df.clone().filter(condition));
        }
        Ok(self)
    }

    /// 选择列
    pub fn select(&mut self, columns: Vec<Expr>) -> PolarsResult<&mut Self> {
        self.to_lazy();
        if let Some(ref lazy_df) = self.lazy_df {
            self.lazy_df = Some(lazy_df.clone().select(&columns));
        }
        Ok(self)
    }

    /// 选择列名
    pub fn select_columns(&mut self, column_names: Vec<&str>) -> PolarsResult<&mut Self> {
        let exprs: Vec<Expr> = column_names.into_iter().map(|name| col(name)).collect();
        self.select(exprs)
    }

    // ==================== 数据转换方法 ====================

    /// 添加新列
    pub fn with_columns(&mut self, exprs: Vec<Expr>) -> PolarsResult<&mut Self> {
        self.to_lazy();
        if let Some(ref lazy_df) = self.lazy_df {
            self.lazy_df = Some(lazy_df.clone().with_columns(&exprs));
        }
        Ok(self)
    }

    /// 重命名列
    pub fn rename_columns(&mut self, renames: HashMap<&str, &str>) -> PolarsResult<&mut Self> {
        self.to_lazy();
        if let Some(ref lazy_df) = self.lazy_df {
            let mut current_lazy = lazy_df.clone();
            for (old_name, new_name) in renames {
                current_lazy = current_lazy.rename(&[old_name], &[new_name]);
            }
            self.lazy_df = Some(current_lazy);
        }
        Ok(self)
    }

    /// 删除列
    pub fn drop_columns(&mut self, columns: Vec<&str>) -> PolarsResult<&mut Self> {
        self.to_lazy();
        if let Some(ref lazy_df) = self.lazy_df {
            self.lazy_df = Some(lazy_df.clone().drop_columns(columns));
        }
        Ok(self)
    }

    // ==================== 聚合方法 ====================

    /// 分组聚合
    pub fn group_by_agg(
        &mut self,
        group_columns: Vec<&str>,
        agg_exprs: Vec<Expr>,
    ) -> PolarsResult<&mut Self> {
        self.to_lazy();
        if let Some(ref lazy_df) = self.lazy_df {
            let group_cols: Vec<Expr> = group_columns.into_iter().map(|col| col(col)).collect();
            self.lazy_df = Some(lazy_df.clone().group_by(&group_cols).agg(&agg_exprs));
        }
        Ok(self)
    }

    /// 按部门统计薪资
    pub fn department_stats(&mut self) -> PolarsResult<&mut Self> {
        let agg_exprs = vec![
            col("salary").mean().alias("avg_salary"),
            col("salary").count().alias("employee_count"),
            col("salary").min().alias("min_salary"),
            col("salary").max().alias("max_salary"),
            col("age").mean().alias("avg_age"),
        ];
        self.group_by_agg(vec!["department"], agg_exprs)
    }

    // ==================== 排序和去重方法 ====================

    /// 排序
    pub fn sort(&mut self, by: &str, descending: bool) -> PolarsResult<&mut Self> {
        self.to_lazy();
        if let Some(ref lazy_df) = self.lazy_df {
            let options = SortOptions {
                descending,
                ..Default::default()
            };
            self.lazy_df = Some(lazy_df.clone().sort(by, options));
        }
        Ok(self)
    }

    /// 多列排序
    pub fn sort_by_multiple(
        &mut self,
        sort_specs: Vec<(&str, bool)>,
    ) -> PolarsResult<&mut Self> {
        self.to_lazy();
        if let Some(ref lazy_df) = self.lazy_df {
            let mut current_lazy = lazy_df.clone();
            for (column, descending) in sort_specs {
                let options = SortOptions {
                    descending,
                    ..Default::default()
                };
                current_lazy = current_lazy.sort(column, options);
            }
            self.lazy_df = Some(current_lazy);
        }
        Ok(self)
    }

    /// 去重
    pub fn distinct(&mut self, columns: Option<Vec<String>>) -> PolarsResult<&mut Self> {
        self.to_lazy();
        if let Some(ref lazy_df) = self.lazy_df {
            self.lazy_df = Some(
                lazy_df
                    .clone()
                    .unique(columns, UniqueKeepStrategy::First),
            );
        }
        Ok(self)
    }

    // ==================== 字符串操作方法 ====================

    /// 字符串处理
    pub fn process_strings(&mut self) -> PolarsResult<&mut Self> {
        self.to_lazy();
        if let Some(ref lazy_df) = self.lazy_df {
            self.lazy_df = Some(lazy_df.clone().with_columns(&[
                col("name").str().to_uppercase().alias("name_upper"),
                col("name").str().to_lowercase().alias("name_lower"),
                col("name").str().lengths().alias("name_length"),
                col("department")
                    .str()
                    .contains(lit("IT"), false)
                    .alias("is_it_department"),
            ]));
        }
        Ok(self)
    }

    // ==================== 时间序列方法 ====================

    /// 时间序列处理
    pub fn process_datetime(&mut self) -> PolarsResult<&mut Self> {
        self.to_lazy();
        if let Some(ref lazy_df) = self.lazy_df {
            self.lazy_df = Some(lazy_df.clone().with_columns(&[
                col("join_date").dt().year().alias("join_year"),
                col("join_date").dt().month().alias("join_month"),
                col("join_date").dt().day().alias("join_day"),
                // 计算工作年限(假设当前日期)
                (lit(2024) - col("join_date").dt().year()).alias("years_of_service"),
            ]));
        }
        Ok(self)
    }

    /// 计算移动平均
    pub fn moving_average(&mut self, column: &str, window_size: usize) -> PolarsResult<&mut Self> {
        self.to_lazy();
        if let Some(ref lazy_df) = self.lazy_df {
            let ma_expr = col(column).rolling_mean(RollingOptions {
                window_size,
                min_periods: 1,
                ..Default::default()
            });
            let alias = format!("{}_ma_{}", column, window_size);
            self.lazy_df = Some(lazy_df.clone().with_columns(&[ma_expr.alias(alias)]));
        }
        Ok(self)
    }

    // ==================== 连接操作方法 ====================

    /// 创建部门信息表用于连接演示
    pub fn create_department_table(&self) -> PolarsResult<DataFrame> {
        let departments = df! [
            "department" => ["IT", "HR", "Finance", "Marketing"],
            "manager" => ["John Doe", "Jane Smith", "Mike Johnson", "Sarah Wilson"],
            "budget" => [1000000.0, 500000.0, 800000.0, 600000.0],
        ]?;
        Ok(departments)
    }

    /// 连接操作
    pub fn join_with_departments(&mut self) -> PolarsResult<&mut Self> {
        let departments = self.create_department_table()?;
        
        self.to_lazy();
        if let Some(ref lazy_df) = self.lazy_df {
            let departments_lazy = departments.lazy();
            self.lazy_df = Some(lazy_df.clone().join(
                departments_lazy,
                [col("department")],
                [col("department")],
                JoinArgs::new(JoinType::Left),
            ));
        }
        Ok(self)
    }

    // ==================== 数据统计方法 ====================

    /// 获取数据统计信息
    pub fn describe(&self) -> PolarsResult<DataFrame> {
        if let Some(ref df) = self.df {
            df.describe(None)
        } else if let Some(ref lazy_df) = self.lazy_df {
            lazy_df.clone().describe().collect()
        } else {
            Err(PolarsError::NoData("No data available".into()))
        }
    }

    /// 获取数值列的相关性矩阵
    pub fn correlation(&self) -> PolarsResult<DataFrame> {
        if let Some(ref df) = self.df {
            let numeric_df = df
                .clone()
                .lazy()
                .select([col("*").exclude([DataType::Utf8, DataType::Categorical, DataType::Boolean])])
                .collect()?;
            numeric_df.corr(2, None)
        } else {
            Err(PolarsError::NoData("No data available".into()))
        }
    }

    // ==================== 数据信息方法 ====================

    /// 显示数据概览
    pub fn show_info(&self) -> PolarsResult<()> {
        if let Some(ref df) = self.df {
            println!("DataFrame 形状: {} 行 × {} 列", df.height(), df.width());
            println!("列信息:");
            for (i, name) in df.get_column_names().iter().enumerate() {
                let dtype = df.column(name)?.dtype();
                println!("  {}: {} ({:?})", i, name, dtype);
            }
            println!("\n前5行数据:");
            println!("{}", df.head(Some(5)));
        } else if let Some(ref lazy_df) = self.lazy_df {
            println!("这是一个 LazyFrame,需要 collect() 后查看数据");
            let plan = lazy_df.clone().describe_plan();
            println!("执行计划:\n{}", plan);
        } else {
            println!("没有数据");
        }
        Ok(())
    }

    // ==================== 转换方法 ====================

    /// 转换为惰性 DataFrame
    pub fn to_lazy(&mut self) -> &mut Self {
        if self.lazy_df.is_none() {
            if let Some(ref df) = self.df {
                self.lazy_df = Some(df.lazy());
            }
        }
        self
    }

    /// 执行计算并获取 DataFrame
    pub fn collect(&mut self) -> PolarsResult<&mut Self> {
        if let Some(ref lazy_df) = self.lazy_df {
            self.df = Some(lazy_df.clone().collect()?);
            self.lazy_df = None;
        }
        Ok(self)
    }

    /// 获取最终的 DataFrame
    pub fn get_dataframe(&self) -> Option<&DataFrame> {
        self.df.as_ref()
    }

    /// 获取最终的 LazyFrame
    pub fn get_lazyframe(&self) -> Option<&LazyFrame> {
        self.lazy_df.as_ref()
    }

    /// 克隆当前数据
    pub fn clone_data(&self) -> PolarsResult<Self> {
        if let Some(ref df) = self.df {
            Ok(Self::from_dataframe(df.clone()))
        } else if let Some(ref lazy_df) = self.lazy_df {
            Ok(Self::from_lazyframe(lazy_df.clone()))
        } else {
            Err(PolarsError::NoData("No data to clone".into()))
        }
    }
}

impl Default for DataDeal {
    fn default() -> Self {
        Self::new()
    }
}

// ==================== 使用示例 ====================

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_basic_operations() -> PolarsResult<()> {
        let mut data_deal = DataDeal::new();
        
        // 创建示例数据
        data_deal.create_sample_data()?
            .show_info()?;

        // 数据处理管道
        data_deal
            .process_strings()?
            .process_datetime()?
            .filter(col("age").gt(lit(30)))?
            .sort("salary", true)?
            .collect()?;

        println!("处理后的数据:");
        if let Some(df) = data_deal.get_dataframe() {
            println!("{}", df);
        }

        // 部门统计
        let mut stats = data_deal.clone_data()?;
        stats.department_stats()?.collect()?;
        println!("部门统计:");
        if let Some(df) = stats.get_dataframe() {
            println!("{}", df);
        }

        Ok(())
    }

    #[test]
    fn test_advanced_operations() -> PolarsResult<()> {
        let mut data_deal = DataDeal::new();
        
        data_deal.create_sample_data()?
            .join_with_departments()?
            .moving_average("salary", 2)?
            .collect()?;

        println!("高级操作结果:");
        data_deal.show_info()?;

        // 相关性分析
        if let Some(df) = data_deal.get_dataframe() {
            let correlation = data_deal.correlation()?;
            println!("相关性矩阵:\n{}", correlation);
        }

        Ok(())
    }
}
```
    

 

    

 

    

 

    

 


 

  

 


DataFrame

 
```
let s1 = Series::new("Name".into(), &["Alice", "Bob", "Charlie"]);
let s2 = Series::new("Age".into(), &[25, 30, 35]);
let s3 = Series::new("City".into(), &["NYC", "LA", "Chicago"]);

// 从 Series 构建 DataFrame
let df = DataFrame::new(vec![
    Column::new("Name".into(), s1),
    Column::new("Age".into(), s2),
    Column::new("City".into(), s3)
])?;

println!("DataFrame:\n{}", df);
let name = df.column("Name")?;
println!("Name column:\n{:?}", name);
```

 
```
DataFrame:
shape: (3, 3)
┌─────────┬─────┬─────────┐
│ Name    ┆ Age ┆ City    │
│ ---     ┆ --- ┆ ---     │
│ str     ┆ i32 ┆ str     │
╞═════════╪═════╪═════════╡
│ Alice   ┆ 25  ┆ NYC     │
│ Bob     ┆ 30  ┆ LA      │
│ Charlie ┆ 35  ┆ Chicago │
└─────────┴─────┴─────────┘
Name column:
Series(SeriesColumn { inner: shape: (3,)
Series: 'Name' [str]
[
        "Alice"
        "Bob"
        "Charlie"
], materialized_at: None })

```
    

 

    

 

    

 

    

 
```
pub fn test_crt1() -> Result<(), Box<dyn std::error::Error>> {

    // 使用宏创建 (更简洁)
    let df2 = df!("Name" => ["Alice", "Bob", "Charlie"],
                  "Age" => [25, 30, 35],
                  "City" => ["NYC", "LA", "Chicago"])?;
    println!("\nUsing df! macro:\n{}", df2);

    Ok(())
}
```
    

 
```
Using df! macro:
shape: (3, 3)
┌─────────┬─────┬─────────┐
│ Name    ┆ Age ┆ City    │
│ ---     ┆ --- ┆ ---     │
│ str     ┆ i32 ┆ str     │
╞═════════╪═════╪═════════╡
│ Alice   ┆ 25  ┆ NYC     │
│ Bob     ┆ 30  ┆ LA      │
│ Charlie ┆ 35  ┆ Chicago │
└─────────┴─────┴─────────┘
```
    

 

    

 


 

  

 


DataType

DataType来自于Polars依赖包,通过use polars::prelude::*;导入。 Polars中可用的主要数据类型包括:

 
- DataType::Null - 空值类型
- DataType::Boolean - 布尔值类型
- DataType::UInt8 - 8位无符号整数
- DataType::UInt16 - 16位无符号整数
- DataType::UInt32 - 32位无符号整数
- DataType::UInt64 - 64位无符号整数
- DataType::Int8 - 8位有符号整数
- DataType::Int16 - 16位有符号整数
- DataType::Int32 - 32位有符号整数
- DataType::Int64 - 64位有符号整数
- DataType::Float32 - 32位浮点数
- DataType::Float64 - 64位浮点数

    

 

    

 

    

 
- DataType::String - 字符串类型
- DataType::Binary - 二进制数据类型
    

 
- DataType::Date - 日期类型(天)
- DataType::Datetime(TimeUnit, Option<String>) - 日期时间类型
- TimeUnit: Nanoseconds, Microseconds, Milliseconds
- Option<String>: 时区(可选)
- DataType::Time - 时间类型
- DataType::Duration(TimeUnit) - 时间段类型

复合类型

 
DataType::List(Box<DataType>) - 列表类型
DataType::Struct(Vec<Field>) - 结构体类型
DataType::Object(String) - 对象类型
  

特殊类型

 
DataType::Categorical - 分类类型(优化存储的字符串)
DataType::Unknown - 未知类型
  

 

  

 


 
```
// 创建数据
let s1 = Series::new("Name".into(), &["Alice", "Bob", "Charlie"]);
let s2 = Series::new("Age".into(), &[25, 30, 35]);
let s3 = Series::new("City".into(), &["NYC", "LA", "Chicago"]);

```
    

0.51版Series要求列类型为PlSmallStr

 
- The Series::new function expects a PlSmallStr for the name parameter instead of a &str. 
- .into() 方法将字符串字面量转换为 PlSmallStr 类型。
    

PlSmallStr 相比 &str 有以下几个主要优势

 
```
1. 内存效率
PlSmallStr 使用小字符串优化(Small String Optimization)
对于短字符串(通常是 23 字节以下),数据直接存储在栈上,避免堆分配
&str 只是字符串引用,不能拥有数据

2. 所有权语义
PlSmallStr 拥有字符串数据,可以自由移动和修改
&str 只是借用,生命周期受限,不能独立存在

3. 性能优化
避免了频繁的堆分配和释放
减少了内存碎片
缓存友好性更好

4. 适合 DataFrame 列名
在 Polars 中,列名通常是短字符串且频繁使用:
// 更高效
let s1 = Series::new("Name".into(), &["Alice", "Bob"]);

// vs 传统方式需要额外的字符串管理
let name: String = "Name".to_string();
let s1 = Series::new(name.into(), &["Alice", "Bob"]);

5. 零拷贝转换
支持从多种字符串类型零拷贝或低成本转换:
"Name".into()           // &str -> PlSmallStr
String::from("Name").into()  // String -> PlSmallStr
这就是为什么 Polars 在内部广泛使用 PlSmallStr 来标识列名和其他元数据。
```
    

 

    

 

    

lit 是 Polars lazy API 中的基础函数,用于在表达式中嵌入常量值。

 
```
lit 是 Polars 中的一个函数,用于创建字面量表达式(Literal Expression)。
lit 的作用:
将值转换为表达式:将普通的 Rust 值(如数字、字符串等)转换为 Polars 可以处理的 Expr 类型
在表达式中使用常量:在复杂的表达式操作中用作常量值

在你的代码中:
let filtered = df.clone().lazy()
    .filter(col("Age").gt(lit(28)))  // lit(28) 将数字28转换为表达式
    .collect()?;
这里 lit(28) 将数字 28 转换为 Polars 表达式,然后才能与 col("Age") 进行 gt(大于)比较。

```
    

 
```

其他常见用法:
// 数字字面量
lit(100)
lit(3.14)

// 字符串字面量  
lit("hello")

// 布尔字面量
lit(true)
lit(false)

// 日期字面量
lit(datetime(2023, 1, 1))

// 在计算中使用
df.with_column((col("price") * lit(1.1)).alias("price_with_tax"))

```

 
```

#[allow(dead_code)]
pub fn test_select() -> Result<(), Box<dyn std::error::Error>> {
    let df = df!("Name" => ["Alice", "Bob", "Charlie", "Diana"],
                 "Age" => [25, 30, 35, 28],
                 "City" => ["NYC", "LA", "Chicago", "NYC"])?;

    // 选择列
    let selected = df.select(vec!["Name", "Age"])?;
    println!("Selected columns:\n{}", selected);

    // 过滤行 (年龄 > 28)
    let filtered = df.clone().lazy()
        .filter(col("Age").gt(lit(28)))
        .collect()?;
    println!("\nFiltered (Age > 28):\n{}", filtered);

    // 排序 (按年龄降序)
    let sorted = df.sort(
        vec!["Age"],
        SortMultipleOptions::new().with_order_descending(true)
    )?;
    println!("\nSorted by Age (desc):\n{}", sorted);

    Ok(())
}

```


 

```
Selected columns:
shape: (4, 2)
┌─────────┬─────┐
│ Name    ┆ Age │
│ ---     ┆ --- │
│ str     ┆ i32 │
╞═════════╪═════╡
│ Alice   ┆ 25  │
│ Bob     ┆ 30  │
│ Charlie ┆ 35  │
│ Diana   ┆ 28  │
└─────────┴─────┘

Filtered (Age > 28):
shape: (2, 3)
┌─────────┬─────┬─────────┐
│ Name    ┆ Age ┆ City    │
│ ---     ┆ --- ┆ ---     │
│ str     ┆ i32 ┆ str     │
╞═════════╪═════╪═════════╡
│ Bob     ┆ 30  ┆ LA      │
│ Charlie ┆ 35  ┆ Chicago │
└─────────┴─────┴─────────┘

Sorted by Age (desc):
shape: (4, 3)
┌─────────┬─────┬─────────┐
│ Name    ┆ Age ┆ City    │
│ ---     ┆ --- ┆ ---     │
│ str     ┆ i32 ┆ str     │
╞═════════╪═════╪═════════╡
│ Charlie ┆ 35  ┆ Chicago │
│ Bob     ┆ 30  ┆ LA      │
│ Diana   ┆ 28  ┆ NYC     │
│ Alice   ┆ 25  ┆ NYC     │
└─────────┴─────┴─────────┘
```

  

 

  

with_column 方法的基本用法

 
```

1. 方法签名
fn with_column<C: IntoColumn>(&mut self, column: C) -> PolarsResult<&mut Self>

2. 主要功能
替换现有列: 用新的列数据替换同名的现有列
添加新列: 如果列名不存在,则添加新列
修改数据类型: 如我们在 data_type_change 中所做的

```
  

 
```

3. 常见用法示例
a 修改现有列的数据类型
// 将某列转换为Float64类型
let casted_column = df.column("Amount")?.cast(&DataType::Float64)?;
df.with_column(casted_column)?;
b 基于现有列创建新列
use polars::prelude::*;

// 创建一个新的计算列
df.with_column(
    (col("price") * col("quantity")).alias("total_amount")
)?;
c 使用函数转换列
// 对列应用函数
df.with_column(
    col("name").str().to_uppercase().alias("upper_name")
)?;

```
  

 
```
4. 在我们的实现中的应用
在 data_type_change 方法中,with_column 用于:
// 1. 获取列
let column = df.column(col_name)?;

// 2. 转换数据类型
let casted_column = column.cast(&DataType::Float64)?;

// 3. 使用with_column替换原列
df_result.with_column(casted_column)?;

```
  

 
```
5. 注意事项
返回值: with_column 返回 &mut DataFrame,所以支持链式调用
列名: 新列会替换同名旧列
所有权: 需要确保 DataFrame 是可变的

6. 其他相关方法
除了 with_column,Polars 还提供了其他列操作方法:
// 添加新列而不替换
df.with_column(
    lit(0).alias("new_column")  // 添加常量列
)?;

// 选择列
df.select(["col1", "col2"])?;

// 删除列
df.drop(["col_to_drop"])?;
所以是的,with_column 是操作 DataFrame 列的核心方法,可以用于数据类型转换、计算新值、应用函数等各种列操作。

```
  

 

  

 
```
// 验证目标列是否存在
let existing_columns: HashSet<&str> = df.get_column_names().iter()
    .map(|name| name.as_str())
    .collect();

let valid_conversions: Vec<(String, DataType)> = type_conversions.into_iter()
    .filter(|(col_name, _)| existing_columns.contains(col_name.as_str()))
    .collect();

```

df.get_column_names().iter() 返回的类型

 
```
let file_path = "/ai/data/tmp/df_tra.csv";
    let data_processor = Dtl::new();
    let df = Dtl::read_csv(file_path).unwrap();

    let column_names = df.get_column_names().to_vec();
    let df_iter = column_names.iter();

    // 遍历列名并打印column_name的类型
    println!("遍历column_name的类型:");
    for column_name in df_iter {
        // 使用TypeId来获取类型信息
        let type_id = std::any::TypeId::of::<&String>();
        let actual_type_id = std::any::type_name_of_val(column_name);
        println!("列名: {:<20} | column_name值: {:<15} | 实际类型: {}",
                 column_name, column_name, actual_type_id);
    }
    println!("--------------------------------------");
```

值得注意的是column_name被使用了两次,这就是引用的好处

 
```
------------------------
遍历column_name的类型:
列名: From                 | column_name值: From            | 实际类型: &polars_utils::pl_str::PlSmallStr
列名: To                   | column_name值: To              | 实际类型: &polars_utils::pl_str::PlSmallStr
列名: Amount               | column_name值: Amount          | 实际类型: &polars_utils::pl_str::PlSmallStr
列名: Currency             | column_name值: Currency        | 实际类型: &polars_utils::pl_str::PlSmallStr
列名: Payment Format       | column_name值: Payment Format  | 实际类型: &polars_utils::pl_str::PlSmallStr
列名: time8                | column_name值: time8           | 实际类型: &polars_utils::pl_str::PlSmallStr
列名: time14               | column_name值: time14          | 实际类型: &polars_utils::pl_str::PlSmallStr
--------------------------------------
```

聚合

 
```

#[allow(dead_code)]
pub fn test_agg() -> Result<(), Box<dyn std::error::Error>> {
    let df = df!("City" => ["NYC", "LA", "Chicago", "NYC", "LA"],
                 "Age" => [25, 30, 35, 28, 32],
                 "Salary" => [50000, 60000, 70000, 55000, 65000])?;

    // 按城市分组,计算年龄和薪水的平均值
    let grouped = df
        .lazy()
        .group_by([col("City")])
        .agg([
            col("Age").mean().alias("avg_age"),
            col("Salary").mean().alias("avg_salary"),
        ])
        .collect()?;
    println!("Grouped by City:\n{}", grouped);

    Ok(())
}
```
    

 

    

 

    

 

    

 


 

  

 


参考