csv 如何解决“错误标记数据”

m4pnthwp  于 6个月前  发布在  其他
关注(0)|答案(6)|浏览(108)

很多问题已经被问到about this topic on SO .(还有很多其他的)。在众多的答案中,到目前为止没有一个对我真正有帮助。如果我错过了**有用的一个,请让我知道。
我只是想把一个带有pandas的CSV文件读到一个框架中。听起来像是一个简单的任务。
我的文件Test.csv

1,2,3,4,5
1,2,3,4,5,6
,,3,4,5
1,2,3,4,5,6,7
,2,,4

字符串
我的代码:

import pandas as pd
df = pd.read_csv('Test.csv',header=None)


我的错误:

pandas.errors.ParserError: Error tokenizing data. C error: Expected 5 fields in line 2, saw 6


我对这个问题的猜测是,Pandas会查看第一行,并期望后面的行中有相同数量的令牌。如果不是这样,它将停止并返回错误。
在众多的答案中,使用选项的建议是,例如:error_bad_lines=Falseheader=Noneskiprows=3以及更多无用的建议。
然而,我不想忽略任何一行或跳过,而且我事先也不知道这个表格有多少行和多少列。
因此,它基本上归结为如何找到最大列数在目录中。这是要走的路吗?我希望有一个简单的方法来简单地读取CSV文件,它没有在第一行的最大列数。谢谢你的任何提示。我使用Python 3.6.3,Pandas 0.24.1在Win7上。

vecaoik1

vecaoik11#

感谢@ALollz提供的“非常新鲜”的链接(幸运的巧合),感谢@Rich Andrews指出我的示例实际上不是“严格正确的”CSV数据。
所以,我目前的工作方式是改编自@ALollz的紧凑解决方案(https://stackoverflow.com/a/55129746/7295599

### reading an "incorrect" CSV to dataframe having a variable number of columns/tokens 
import pandas as pd

df = pd.read_csv('Test.csv', header=None, sep='\n')
df = df[0].str.split(',', expand=True)
# ... do some modifications with df
### end of code

字符串
df包含空字符串''用于开头和中间的缺失条目,None用于结尾的缺失标记。

0  1  2  3     4     5     6
0  1  2  3  4     5  None  None
1  1  2  3  4     5     6  None
2        3  4     5  None  None
3  1  2  3  4     5     6     7
4     2     4  None  None  None


如果您通过以下方式再次将此内容写入文件:
df.to_csv("Test.tab",sep="\t",header=False,index=False)
None将被转换为空字符串'',一切正常。
下一个层次是考虑包含分隔符的引号中的数据字符串,但这是另一个主题。

1,2,3,4,5
,,3,"Hello, World!",5,6
1,2,3,4,5,6,7

pieyvz9o

pieyvz9o2#

使用tolerant python csv模块读取csv,并在将其交给pandas之前修复加载的文件,这将在其他格式错误的csv数据上失败,而不管pandas使用的是什么csv引擎。

import pandas as pd
import csv

not_csv = """1,2,3,4,5
1,2,3,4,5,6
,,3,4,5
1,2,3,4,5,6,7
,2,,4
"""

with open('not_a.csv', 'w') as csvfile:
    csvfile.write(not_csv)

d = []
with open('not_a.csv') as csvfile:
    areader = csv.reader(csvfile)
    max_elems = 0
    for row in areader:
        if max_elems < len(row): max_elems = len(row)
    csvfile.seek(0)
    for i, row in enumerate(areader):
        # fix my csv by padding the rows
        d.append(row + ["" for x in range(max_elems-len(row))])

df = pd.DataFrame(d)
print df

# the default engine
# provides "pandas.errors.ParserError: Error tokenizing data. C error: Expected 5 fields in line 2, saw 6 "
#df = pd.read_csv('Test.csv',header=None, engine='c')

# the python csv engine
# provides "pandas.errors.ParserError: Expected 6 fields in line 4, saw 7 "
#df = pd.read_csv('Test.csv',header=None, engine='python')

字符串
python外部的预处理文件,如果担心python内部的额外代码会创建太多python代码。

Richs-MBP:tmp randrews$ cat test.csv
1,2,3
1,
2
1,2,
,,,
Richs-MBP:tmp randrews$ awk 'BEGIN {FS=","}; {print $1","$2","$3","$4","$5}' < test.csv
1,2,3,,
1,,,,
2,,,,
1,2,,,
,,,,

wi3ka0sx

wi3ka0sx3#

我有一个不同的解决方案,让pandas负责创建表和删除None值,让我们负责编写一个适当的标记器。

Tokenizer

def tokenize(str):
    idx = [x for x, v in enumerate(str) if v == '\"']
    if len(idx) % 2 != 0:
        idx = idx[:-1]
    memory = {}
    for i in range(0, len(idx), 2):
        val = str[idx[i]:idx[i+1]+1]
        key = "_"*(len(val)-1)+"{0}".format(i)
        memory[key] = val
        str = str.replace(memory[key], key, 1)        
    return [memory.get(token, token) for token in str.split(",")]

字符串

Tokenizer测试用例

print (tokenize("1,2,3,4,5"))
print (tokenize(",,3,\"Hello, World!\",5,6"))
print (tokenize(",,3,\"Hello,,,, World!\",5,6"))
print (tokenize(",,3,\"Hello, World!\",5,6,,3,\"Hello, World!\",5,6"))
print (tokenize(",,3,\"Hello, World!\",5,6,,3,\"Hello,,5,6"))


输出
第一个月

将分词器投入使用

with open("test1.csv", "r") as fp:
    lines = fp.readlines()

lines = list(map(lambda x: tokenize(x.strip()), lines))
df = pd.DataFrame(lines).replace(np.nan, '')

优点:

现在我们可以根据我们的需要teak tokenizer函数

kg7wmglp

kg7wmglp4#

在我的例子中,1我在Excel中打开 *.csv 2我将 *.csv保存为CSV(逗号分隔)3我通过以下方式在python中加载文件:

import pandas as pd
df = pd.read_csv('yourcsvfile.csv', sep=',')

字符串
希望有帮助!

gr8qqesn

gr8qqesn5#

对我来说,解决方案是添加正确的分隔符;,如下所示:
pandas.read_csv(path, sep=';')

1mrurvl1

1mrurvl16#

对我来说,这是通过将usecols添加到pd.read_csv()命令来解决的:
usecols='My_Column_1','My_Column_2',.]

相关问题