Tenho um arquivo tsv que contém inteiros com separadores de milhar. Estou tentando lê-lo usando polars==1.6.0
, a codificação éutf-16
from io import BytesIO
import polars as pl
data = BytesIO(
"""
Id\tA\tB
1\t537\t2,288
2\t325\t1,047
3\t98\t194
""".encode("utf-16")
)
df = pl.read_csv(data, encoding="utf-16", separator="\t")
print(df)
Não consigo descobrir como fazer com que os polares tratem a coluna "B" como um inteiro em vez de uma string, e também não consigo encontrar uma maneira limpa de convertê-la em um inteiro.
shape: (3, 3)
┌────────┬─────┬───────┐
│ Id ┆ A ┆ B │
│ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ str │
╞════════╪═════╪═══════╡
│ 1 ┆ 537 ┆ 2,288 │
│ 2 ┆ 325 ┆ 1,047 │
│ 3 ┆ 98 ┆ 194 │
└────────┴─────┴───────┘
cast falha, assim como passar o esquema explicitamente. Eu também tentei usar str.strip_chars
e para remover a vírgula, minha solução alternativa é usar str.replace_all
em vez disso.
df = df.with_columns(
pl.col("B").str.strip_chars(",").alias("B_strip_chars"),
pl.col("B").str.replace_all("[^0-9]", "").alias("B_replace"),
)
print(df)
shape: (3, 5)
┌────────┬─────┬───────┬───────────────┬───────────┐
│ Id ┆ A ┆ B ┆ B_strip_chars ┆ B_replace │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ str ┆ str ┆ str │
╞════════╪═════╪═══════╪═══════════════╪═══════════╡
│ 1 ┆ 537 ┆ 2,288 ┆ 2,288 ┆ 2288 │
│ 2 ┆ 325 ┆ 1,047 ┆ 1,047 ┆ 1047 │
│ 3 ┆ 98 ┆ 194 ┆ 194 ┆ 194 │
└────────┴─────┴───────┴───────────────┴───────────┘
Além disso, para que isso funcione em geral, preciso garantir que read_csv
ele não tente inferir tipos para nenhuma coluna, para que eu possa convertê-los manualmente (qualquer coluna numérica com um valor > 999 conterá uma vírgula)
Para permitir possíveis
,
separadores múltiplos, use .str.replace_all:que fornece para os dados da amostra:
Se seus dados de origem forem utf-16 (ou qualquer coisa além de utf-8), o polars os converterá para utf-8 por meio do python. Como isso precisa acontecer de qualquer maneira, pode ser melhor fazer essa conversão você mesmo e substituir os ","s no meio para que o leitor nativo de csv polars analise os dados como números no
read_csv
início em vez de em uma etapa subsequenteSó para enfatizar que se seus dados de origem já são utf-8, então fazer o python fazer isso
replace
é quase certamente mais lento do que a resposta de @user19077881. Só faça isso se sua origem não for utf-8 porque o polars irá convertê-la para utf-8 em python de qualquer maneira. Claro, se você tem colunas que são supostamente strings com vírgulas, então isso não funciona porque ele não sabe a diferença.