自之前关于 DuckDB 的帖子后,一直在使用并享受 DuckDB。最近想分析和可视化一些金融 CSV 文件,包括合并几个文件,开始用 Polars 但觉得其语法令人困惑且繁琐。
- 以解析
Transactions.csv
并按Category
求和为例,Polars 代码如下:
df = pl.read_csv("Transactions.csv") df = ( df.select("Date", "Category", "Amount") .with_columns( pl.col("Date").str.to_date("%m/%d/%Y"), pl.col("Amount") .map_elements(lambda amount: amount.replace("$", "")) .str.to_decimal(), ) .filter(pl.col("Date") > datetime.date(2024, 1, 1)) .group_by("Category") .agg(pl.col("Amount").sum()) ) print(df)
- 遇到的问题:选择和转换列的语法、解析日期列的方式、写 lambda 去除
$
(或许有更好方法)、df.
和pl.
调用的混合等。
- 以解析
相比之下,因日常写 SQL,觉得用 DuckDB 更易,可写更熟悉的 SQL 并结合 Python 代码:
results = duckdb.sql( """ select Category, sum(replace(Amount, '$', '')::decimal) as Amount from read_csv('Transactions.csv') where Date > '2024-01-01' group by Category """ ) results.show()
且可通过 SQL 合并多个 CSV 文件并添加更复杂的
WHERE
条件:results = duckdb.sql( """ select c.Group, sum(replace(t.Amount, '$', '')::decimal) as Amount from read_csv('Transactions.csv') t join read_csv('Categories.csv') c on c.Category = t.Category where t.Date > '2024-01-01' and c.Type in ('Income', 'Expense') group by c.Group """ ) results.show()
注意 DuckDB 能自动解析日期列。
更新:Reddit 评论展示了去除
map_elements
的方法:pl.col("Amount").str.replace("\\$", "").str.to_decimal()
但认为双重使用
.str
对非频繁使用者较复杂。另一个 Reddit 评论展示了“更短(无中间步骤)且更高效(扫描)的版本”:
df = ( pl.scan_csv("Transactions.csv") .filter(pl.col("Date").str.to_date("%m/%d/%Y") > datetime.date(2024, 1, 1)) .group_by("Category") .agg(pl.col("Amount").str.replace("\\$", "").str.to_decimal().sum()) .collect() ) print(df)
有关于此帖的讨论,尤其是围绕 Polars/Pandas 增加的组合性与 SQL 对比以及更好写 Polars 代码的方式:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。