我有一个极DataFrame与多个数字(float dtype)列。我想把其中的一些写入csv文件,其中有一定的小数位数。我想要的小数位数是特定于列的。
polars
提供格式:
import polars as pl
df = pl.DataFrame({"a": [1/3, 1/4, 1/7]})
df.select(
[
pl.format("as string {}", pl.col("a")),
]
)
shape: (3, 1)
┌───────────────────────────────┐
│ literal │
│ --- │
│ str │
╞═══════════════════════════════╡
│ as string 0.3333333333333333 │
│ as string 0.25 │
│ as string 0.14285714285714285 │
└───────────────────────────────┘
但是,如果我试图设置一个指令来指定小数位数,它会失败:
df.select(
[
pl.format("{:.3f}", pl.col("a")),
]
)
ValueError:占位符的数量应该等于参数的数量
是否有"real"不使用apply
的f字符串功能?
pl.__version__: '0.16.16'
- related: Polars:在DataFrame内切换数据类型
- 设置所有输出列的小数点后十位,pl.DataFrame。write_csv提供
float_precision
关键字
使用round
如何?
的例子:
df.select(
[
pl.format("as string {}", pl.col("a").round(3)),
]
)
shape: (3, 1)
┌─────────────────┐
│ literal │
│ --- │
│ str │
╞═════════════════╡
│ as string 0.333 │
│ as string 0.25 │
│ as string 0.143 │
└─────────────────┘
如果所有颜色的小数数相同,则write_csv
方法上的float_precision
就足够了:
df = pl.DataFrame( {"colx": [1/3, 1/4, 1/7, 2]} )
print( df.write_csv( None,float_precision=3 ) )
# colx
# 0.333
# 0.250
# 0.143
# 2.000
否则,您可以使用这个(略显笨拙)实用函数来获得所需的逐列"float→string"舍入行为(包括后面的零-如果你不需要后面的零,那么坚持使用@Luca的"round";方法,因为它将更性能),然后,然后导出到CSV:
def round_str( col:str, n:int ):
return (
pl.col( col ).round( n ).cast( str ) + pl.lit( "0"*n )
).str.replace( rf"^(d+.d{{{n}}}).*$","$1" ).alias( col )
的例子:
df = pl.DataFrame(
{
"colx": [1/3, 1/4, 1/7, 2.00],
"coly": [1/4, 1/5, 1/6, 1.00],
"colz": [3/4, 7/8, 9/5, 0.09],
}
).with_columns(
round_str( "colx",5 ),
round_str( "coly",3 ),
round_str( "colz",1 ),
)
# ┌─────────┬───────┬──────┐
# │ colx ┆ coly ┆ colz │
# │ --- ┆ --- ┆ --- │
# │ str ┆ str ┆ str │
# ╞═════════╪═══════╪══════╡
# │ 0.33333 ┆ 0.250 ┆ 0.8 │
# │ 0.25000 ┆ 0.200 ┆ 0.9 │
# │ 0.14286 ┆ 0.167 ┆ 1.8 │
# │ 2.00000 ┆ 1.000 ┆ 0.1 │
# └─────────┴───────┴──────┘
print( df.write_csv(None) )
# colx,coly,colz
# 0.33333,0.250,0.8
# 0.25000,0.200,0.9
# 0.14286,0.167,1.8
# 2.00000,1.000,0.1
(理想情况下,write_csv
上的float_precision
参数允许使用字典;TODO列表的东西;)