读取列之间带有换行符的csv文件

2024-05-16 21:09:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经用分号pandas来读取和解析csv文件。有些文件(由于未知原因)在某些列后面有一个'\r\n'序列,这使得pandas.read_csv将它们拆分为不同的行。我想对这些字符进行转义,并将“第二行”附加到“第一行”上,否则之后解析就会变得困难。你知道吗

我可以识别这些行,因为它们后面是数字,而正确的第一列包含时间,如00:00:00。有没有可能用pandas.read_csv做到这一点?你知道吗


示例

如果文件正确,我的代码如下所示:

data = io.StringIO( ''' a; b; c; d 
                    x10; 20; 30; 40
                    x11; 21; 31; 41
                    x12; 22; 32; 42
                    x13; 23; 33; 43
                    x14; 24; 34; 44
                    x15; 25; 35; 45
                 ''' )

pd.read_csv( data, sep=';' )

输出:

    a   b   c   d
0   10  20  30  40
1   11  21  31  41
2   12  22  32  42
3   13  23  33  43
4   14  24  34  44
5   15  25  35  45

问题

对于一个损坏的文件,它看起来是这样的:

data = io.StringIO( ''' a; b; c; d 
                        x10; 20; 30; 40
                        x11; 21; 31; 41
                        x12; 22; 
                        32; 42
                        x13; 23; 33; 43
                        x14; 24; 34; 44
                        x15; 25; 35; 45
                     ''' )

pd.read_csv( data, sep=';' )

输出:

    a   b   c   d
0   x10     20  30  40.0
1   x11     21  31  41.0
2   x12     22      NaN
3   32  42  NaN     NaN
4   x13     23  33  43.0
5   x14     24  34  44.0
6   x15     25  35  45.0

然而,在这两种情况下,预期产出都是第一位的。在这个例子中,我想用\d\d替换\r\n\d\d,以便在pandas中构建数据帧之前/期间除去那些换行符。你知道吗

如果可能的话,我希望避免先修复文件,避免在与pandas一起阅读之前制作一个额外的脚本来检查所有文件,因为有新文件定期出现。你知道吗


在pandas中读取csv文件时,是否可以替换字符串的一部分?你知道吗

这类问题还有别的解决办法吗?你知道吗


使用python 3.6.8、0.24.2


Tags: 文件csviopandasreaddatananpd
2条回答

这是大型csv经常发生的事情。我解决这个问题的方法是使用python读取它们,并检查分隔符的数量是否与您期望的匹配,否则就删除该行。一旦原始数据被纠正,您就可以使用StringIO将其加载到pandas中。一个例子胜过你的错误例子:

# We load the file
filestream = open(filepath)

# Now we filter the data as follows
data = filter(lambda l: l.count(";")==3, filestream)

# Now we convert to String IO
stream = io.StringIO("\n".join(data))

# And finally we read with Pandas
pd.read_csv(stream, sep=';' )

我从ivallesp's answer得到了零件,并想出了一个解决方案来保持虚线。你知道吗

我把它贴在这里作为未来我的文档(他们经常会忘记这些事情)以及其他可能遇到类似问题的人的文档。你知道吗


坏文件,有断线

infile = io.StringIO( ''' a; b; c; d 
                        x10; 20; 30; 40
                        x11; 21; 31; 41
                        x12; 22; 
                        32; 42
                        x13; 23; 33; 43
                        x14; 24; 34; 44
                        x15; 25; 35; 45
                     ''' )

# The lines are joined with a \n, and whitespace stripped
data = '\n'.join( [ item.strip() for item in infile ] )
# Now data is not a file stream, but a string, with \n s in between

#Search for occurrences of newline + NOT(x + number) and just keep
# found group 
data = re.sub( '\n(?!x\d\d)', '\1', data )

# Now data is a file stream again
data = io.StringIO( data )

# Fed to pandas.read_csv
pd.read_csv( data, sep=';' )

变化

对于磁盘中的实际文件(不是io.StringIO),我不得不做一个小的修改,删除.strip(),不知道为什么。除此之外,它还可以无连接(''.join(...))。你知道吗

最后,我的实际文件在第一列中有时间,形式是00:0000:05等等。所以我实际上是这样用的:

import re

with open( 'broken_rows_file.csv', 'r' ) as infile:
    data = ''.join( [ item for item in infile ] )

#All that is NOT ##:## should be replaced
data = re.sub( '\n(?!\d\d:\d\d)', '\1', data ) 
data = io.StringIO( data )

df = pd.read_csv( data, sep=';' )
df

       a    b   c   d
0   00:10   20  30  40
1   00:11   21  31  41
2   00:12   22  32  42
3   00:13   23  33  43
4   00:14   24  34  44
5   00:15   25  35  45

相关问题 更多 >