我有一个CSV文件,我使用Python来解析。我发现文件中有些行有不同的列数。
001;Snow,Jon;19801201
002;Crom,Jake;19920103
003; ;Wise,Frank;19880303 <-- Invalid row
004;Wiseau,Tommy;4324;1323;2323 <-- Invalid row
我想把这些无效的行写入一个单独的文本文件。
我使用这行代码从文件中读取。
df = pd.read_csv('names.csv', header=None,sep=';')
我在这里找到的一个解决方案是使用以下代码跳过有问题的行:
data = pd.read_csv('file1.csv', on_bad_lines='skip')
我可以从'skip'更改为'warn',这将给出有问题行的行号并跳过该行。但这将返回警告消息,而不是行本身。
由于pandas
1.4.0允许callable
为on_bad_lines
参数——允许你对坏行应用更复杂的处理。
1.4.0新版功能:
callable, function with signature (bad_line: list[str]) -> list[str] | None that will process a single bad line. bad_line is a
按sep分隔的字符串列表。如果函数返回None,则错误的线路将被忽略。如果函数返回一个新的列表字符串的元素多于预期,则会发出ParserWarning删除额外元素时触发。仅支持以下情况:引擎="python">
所以你可以传递一个自定义函数,它会将遇到的坏行写入特定的文件并返回None
(在生成数据帧时跳过该行)。
from functools import partial
def write_bad_line(line, fp, sep=','):
fp.write(sep.join(line) + 'n')
return None # return None to skip the line while processing
bad_lines_fp = open('bad_lines.csv', 'a')
df = pd.read_csv('test.csv', header=None, sep=';', engine='python',
on_bad_lines=partial(write_bad_line, sep=';', fp=bad_lines_fp))
bad_lines_fp.close()
print(df)
数据帧的输出:
0 1 2
0 1 Snow,Jon 19801201
1 2 Crom,Jake 19920103
bad_lines.csv
的内容(通过cat
命令):
$ cat bad_lines.csv
003; ;Wise,Frank;19880303
004;Wiseau,Tommy;4324;1323;2323
您可以在加载Pandas之前运行脚本拆分csv文件。例如,
with open('names.csv') as src, open('good.csv', 'w') as good, open('bad.csv', 'w') as bad:
for line in src:
if line.count(';') == 2: # or any other appropriate criteria
good.write(line)
else:
bad.write(line)