在读取凌乱的 csv 文件时,由于列中数据类型的不一致,我经常会看到不同类型的错误,例如:
ComputeError: Could not parse `22.4` as dtype Int64 at column 59.
The current offset in the file is 433793 bytes.
当文件/数据还不熟悉时,我可能不知道第 59 位的列的名称是什么。我正在寻求比我目前正在做的更有效的流程的建议来克服此类问题:
1 - 首先,我读取文件,并将读取器选项设置为“infer_schema_length=0”(以 pl.Utf8 字符串格式读取数据)。另一种选择是使用“ignore_erros = True”,但据我了解,它将错误值转换为空值,这通常是我不想要的。
2 - 因为我还不知道哪一列是第 59 列,所以我做了一个 for 循环来找出它
for i in enumerate(df.columns):
print(i)
3 - 一旦我计算出引发错误的列名称,我将过滤数据框以找到该特定值来识别它出现在哪一行:
(pl
.read_csv(file="file_name.csv", infer_schema_length=0)
.with_row_count()
.select(
[
pl.col("row_nr"),
pl.col("Error Column Name")
])
.filter(pl.col("Error Column Name") == "22.4")
)
输出:
shape: (1, 2)
┌────────┬───────────────────┐
│ row_nr ┆ Error Column Name │
│ --- ┆ --- │
│ u32 ┆ str │
╞════════╪═══════════════════╡
│ 842 ┆ 22.4 │
└────────┴───────────────────┘
4 - 然后根据文件和情况,但我会在文件源中将值调整为“224”或“22”或“23”,或者修改 DF 并转换所有其他列数据类型为所需的数据类型。
问题:
- 是否有比第 2 步中更简单的方法来访问 Polars 中的第 n 列?
- 是否有更优化的方法来克服导致错误的值?
- 如果我将文件和列读取为 pl.Utf8 并调整导致错误的值,是否有一种方便的方法可以在读取数据后自动检测 df 列的最佳数据类型,而不是手动逐列读取?
最佳答案
来自docs默认的 infer_schema_length
为 100。这意味着如果您有一列的前 100 个值是安全的整数,那么它将将该列的数据类型分配为整数。当它到达 float 时,它会出错,而不是返回并重置数据类型。讽刺的是,您以错误的方向更改默认值以获得您想要的结果。
因此,不必执行 pl.read_csv(file="file_name.csv", infer_schema_length=0)
然后手动转换值,只需执行 pl.read_csv(file="file_name .csv”,infer_schema_length=int(1e10))
。如果仍然出现错误,则将 1e10
调大,如果速度太慢,则将其调小。
这回答了你的问题2。
Q1:您不需要循环遍历所有值,只需执行 df.columns[59]
即可获取第 59 列。另外,不要只是读取整个 df获取列名,您可以这样做 pl.read_csv("file_name.csv", n_rows=1)
这将占用更小的内存占用
问题 3:是/否。这取决于您认为方便的方式以及您要打开的文件格式的范围。如果您只想拥有尝试 int、尝试 float、保留 utf 的层次结构,那么您可以这样做:
for i in df.columns:
try:
df=df.with_column(pl.col(i).cast(pl.Int64()))
continue
except:
pass
try:
df=df.with_column(pl.col(i).cast(pl.Float64()))
continue
except:
pass
关于python - Polars 读取文件导致错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75101128/