我已使用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
但是,两种情况下的预期输出都是第一个。在此示例中,我认为在{/ 1}}中将\r\n\d\d
替换为\d\d
可以消除在熊猫构建数据框之前/期间的那些换行符。
如果可能的话,我想避免先修复文件,避免制作额外的脚本来检查所有文件,然后再读取大熊猫,因为有新文件定期出现。
读取熊猫中的csv文件时是否可以替换字符串的一部分?
还有另一种解决此类问题的方法吗?
使用python 3.6.8,pandas 0.24.2
答案 0 :(得分:1)
大型csv通常会发生这种情况。解决该问题的方法是使用python读取它们,并检查分隔符的数量是否符合您的期望,否则请删除该行。然后,在更正原始数据后,您可以使用StringIO
将其加载到熊猫中。错误示例的示例:
# 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=';' )
答案 1 :(得分:0)
我从ivallesp's answer那里得到了零件,并想出了一种解决方案,可以保留虚线。
我将其发布在这里,作为将来我(常常倾向于忘记此类事情)以及其他可能遇到类似问题的文档。
错误的文件,带有虚线
$userId = 2; // id of chris
$sql = <<<SQL
UPDATE u
SET u.vehicle_desc = v.vehicle
FROM users u
INNER JOIN vehicles v ON v.id = u.vehicle_id
WHERE u.id = ?
SQL;
\DB::statement($sql, [$userId]);
变化
在磁盘中有一个实际文件(不是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