Python csv的分隔符比必要的要少



我有一个csv文件有错误。有些行有4个分隔符(;(,而大多数行有5个分隔符。我有时有4个分隔符的原因是因为有时第二列缺失。

示例:

var1;var2;var3;var4;var5
1;10;john;40;56
2;mary;34;78
3;90.0;smith;52;45

如果我导入csv文件:

import pandas as pd
df=pd.read_csv('myfile.csv', sep=";")

我获得数据帧:

var1 var2  var3  var4 var5
1    10    john  40   56
2    mary  34    78
3    90.0  smith 52   45

我想要:

var1 var2  var3  var4 var5
1    10    john  40   56
2    NaN   mary  34    78
3    90.0  smith 52   45

也许我可以把数据帧分成两部分(一部分是5";",另一部分是4";"(,并在最后附加。我从代码开始:

import csv
with open('myfile.csv',newline='') as fin, open('output.csv','w',newline='') as fout:
reader = csv.reader(fin)
writer = csv.writer(fout)
for row in reader:
if len(row) > 4:
writer.writerow(row)

但是我得到了错误:";行包含NUL";。

解决方法可以是shift数据帧的一部分:

# read with shifted columns
df = pd.read_csv('myfile.csv', sep=';')
# identify rows with incorrect data
m = df['var5'].isna()
# define columns to correct (second to last)
cols = df.columns[1:]
# correct the invalid rows
df.loc[m, cols] = df.loc[m, cols].shift(axis=1)

输出:

var1  var2   var3 var4  var5
0     1    10   john   40  56.0
1     2  None   mary   34  78.0
2     3  90.0  smith   52  45.0

如果需要,可以按照以下方式预处理file.csv插入;,让file.csv内容为

var1;var2;var3;var4;var5
1;10;john;40;56
2;mary;34;78
3;90.0;smith;52;45

然后

with open("file.csv","r") as fin, open("file_fixed.csv","w") as fout:
for line in fin:
if line.count(';') == 3:
line = line.replace(';',';;',1)
fout.write(line)

确实创建了具有以下内容的file_fixed.csv

var1;var2;var3;var4;var5
1;10;john;40;56
2;;mary;34;78
3;90.0;smith;52;45

说明:如果线路有3个;,则使用;;替换;一次(即使用;;仅替换第一个;(

另一种可能的解决方案,基于numpy.rollpandas.DataFrame.apply:

df = pd.read_csv('myfile.csv', sep=';')
df.iloc[:, 1:] = df.iloc[:, 1:].apply(
lambda x: np.roll(x, 1) if np.isnan(x[3]) else x, axis=1)

输出:

var1  var2   var3 var4  var5
0     1    10   john   40  56.0
1     2   NaN   mary   34  78.0
2     3  90.0  smith   52  45.0

关于您最终遇到的特定错误,通过打开"output.csv",您会发现它不包含任何内容,这就是为什么当您尝试打开它时会抛出错误(我想是通过使用pd.read_csv?(。

如果你在阅读循环中添加一行print,你会注意到每一行都是一个字符串的1元素列表,你的值用分号分隔,而不是5元素的值列表。

这是因为你必须告诉你的阅读器方法你使用分号作为分隔符(而不是默认的,(。因此,如果您为读取器和写入器指定分隔符;,它将创建一个新的csv文件,其中只有没有缺失值的行:

import csv
with open('myfile.csv',newline='') as fin, open('output.csv','w',newline='') as fout:
reader = csv.reader(fin, delimiter = ';')
writer = csv.writer(fout, delimiter = ';')
for row in reader:
print(row)
if len(row) > 4:
writer.writerow(row)

希望这能帮助

相关内容

  • 没有找到相关文章

最新更新