import io
import numpy as np
import pandas as pd
csv = io.StringIO('\u0000\u0002a\u0002b\u0001\u0000\u0002c\u0002d\u0001')
for a, b, c in pd.read_csv(
csv, names=range(3), lineterminator='\u0001', delimiter='\u0002'
).replace(np.nan, None).to_numpy():
print(a, b, c)
with (
open("input.csv") as f_in,
open("fixed.csv", "w") as f_out,
):
txt = f_in.read()
txt = txt.replace("\u0001", "\n") # add line endings that CSV reader recognizes
txt = txt.replace("\u0000", "") # go ahead and clear out \u0000
f_out.write(txt)
型 然后像这样阅读CSV:
import csv
with open("fixed.csv", newline="", encoding="utf-8") as f:
reader = csv.reader(f, delimiter="\u0002")
for row in reader:
print(row)
2条答案
按热度按时间oknwwptz1#
您可以使用
pandas.read_csv
,因为它支持替代字符作为行结束符,并将'\u0000'
转换为np.nan
,以便您可以使用DataFrame.replace
方法轻松地将其替换为None
。请注意,您必须事先知道CSV中的列数,以便将一系列数字作为列名传递给它。然后您可以将Rename转换为numpy数组进行迭代:
字符串
这将产生:
型
你也可以使用
tolist
方法将numpy数组转换为列表的列表:型
其输出:
型
zpf6vheq2#
我认为在将文件传递给CSV阅读器之前需要对它进行预处理,因为CSV阅读器无法单独满足您的两个期望:
lineterminator
仅适用于writer,来自docs^1:读取器被硬编码为将
'\r'
或'\n'
识别为行尾,并忽略 * linetimator *。这种行为将来可能会改变。由于您的两个字符对CSV阅读器没有意义,我认为您需要对文件进行预处理,并将它们替换为有意义的值。
给定一个输入文件,如:
可能会像这样预处理文件:
型
然后像这样阅读CSV:
型
来获取类似于以下内容的行变量:
型
我选择清除
\u0000
值,因为CSV读取器不会将空解释为None;写入器会将None解释为空。尽管如此,CSV文件中的空字段是正常的。如果你不想在预处理中替换
\u0001
,那么内部的行将看起来像这样:型
您可以根据需要处理
'\x00'
。