Python 读取列之间带有换行符的csv文件
我已经使用Python 读取列之间带有换行符的csv文件,python,pandas,csv,dataframe,Python,Pandas,Csv,Dataframe,我已经使用pandas,分号分隔的列,读取并解析了csv文件。某些文件(由于未知原因)在某些列后面有一个'\r\n'序列,这使得熊猫。read\u csv将它们拆分到不同的行中。我想对这些字符进行转义,并将“第二行”附加到“第一行”之后,否则之后解析就会变得困难 我可以识别这些行,因为它们后面是数字,而正确的第一列包含时间,如00:00:00。有没有可能用熊猫阅读csv 示例 如果文件正确,我的代码如下所示: data = io.StringIO( ''' a; b; c; d
pandas
,分号分隔的列,读取并解析了csv文件代码>。某些文件(由于未知原因)在某些列后面有一个'\r\n'
序列,这使得熊猫。read\u csv
将它们拆分到不同的行中。我想对这些字符进行转义,并将“第二行”附加到“第一行”之后,否则之后解析就会变得困难
我可以识别这些行,因为它们后面是数字,而正确的第一列包含时间,如00:00:00
。有没有可能用熊猫阅读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=';' )
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=';' )
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
输出:
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
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
问题
如果文件已损坏,则如下所示:
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=';' )
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=';' )
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
输出:
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
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文件时,是否可以替换字符串的一部分
有没有其他办法解决这类问题
使用Python3.6.8,pandas 0.24.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=';' )
我从中获得了零件,并提出了一种解决方案,可以保留断开的线
我把它贴在这里,作为未来我(他们往往会忘记这些事情)和其他可能遇到类似问题的人的文档
坏文件,有断线
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:00
,00:05
等等。所以我实际上是这样用的:
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=';' )
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=';' )
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
你好我想保留这些虚线,所以我更改了过滤器
,以搜索我希望出现在文件中的正则表达式。我将在下面发布我自己的答案以供参考。无论如何,你为我指明了正确的方向,谢谢!谢谢你的留言。是的,这是一个可以调整的通用示例:)