【问题标题】:Pandas Bad Lines Warning CapturePandas 坏行警告捕获
【发布时间】:2015-11-26 21:18:54
【问题描述】:

Pandas 中是否有任何方法可以捕获通过设置 error_bad_lines = False 和 warn_bad_lines = True 产生的警告?例如以下脚本:

import pandas as pd
from StringIO import StringIO
data = StringIO("""a,b,c
                   1,2,3
                   4,5,6
                   6,7,8,9
                   1,2,5
                   3,4,5""")
pd.read_csv(data, warn_bad_lines=True, error_bad_lines=False)

产生警告:

Skipping line 4: expected 3 fields, saw 4

我想将此输出存储到一个字符串中,以便最终将其写入日志文件以跟踪被跳过的记录。

我尝试使用 warning 模块,但它看起来不像这个“警告”是传统意义上的。我正在使用 Python 2.7 和 Pandas 0.16。

任何帮助将不胜感激。

【问题讨论】:

  • 可以打印坏线吗?

标签: python-2.7 pandas


【解决方案1】:

我认为它没有在 pandas 上实现。
source1, source2

我的解决方案:

1.处理前或处理后

import pandas as pd
import csv      

df = pd.read_csv('data.csv', warn_bad_lines=True, error_bad_lines=False)

#compare length of rows by recommended value:
RECOMMENDED = 3

with open('data.csv') as csv_file:
    reader = csv.reader(csv_file, delimiter=',')
    for row in reader:
        if (len(row) != RECOMMENDED):
            print ("Length of row is: %r" % len(row) )
            print row

#compare length of rows by length of columns in df
lencols = len(df.columns)
print lencols

with open('data.csv') as csv_file:
    reader = csv.reader(csv_file, delimiter=',')
    for row in reader:
        if (len(row) != lencols):
            print ("Length of row is: %r" % len(row) )
            print row

2。替换 sys.stdout

import pandas as pd
import os
import sys

class RedirectStdStreams(object):
    def __init__(self, stdout=None, stderr=None):
        self._stdout = stdout or sys.stdout
        self._stderr = stderr or sys.stderr

    def __enter__(self):
        self.old_stdout, self.old_stderr = sys.stdout, sys.stderr
        self.old_stdout.flush(); self.old_stderr.flush()
        sys.stdout, sys.stderr = self._stdout, self._stderr

    def __exit__(self, exc_type, exc_value, traceback):
        self._stdout.flush(); self._stderr.flush()
        sys.stdout = self.old_stdout
        sys.stderr = self.old_stderr


if __name__ == '__main__':

    devnull = open('log.txt', 'w')

    #replaces sys.stdout, sys.stderr, see http://stackoverflow.com/a/6796752/2901002
    with RedirectStdStreams(stdout=devnull, stderr=devnull):
        df = pd.read_csv('data.csv', warn_bad_lines=True, error_bad_lines=False)

【讨论】:

  • 谢谢!我可能会选择第二种解决方案,因为我需要遍历多个文件,不幸的是我们被这种格式卡住了。
【解决方案2】:

对于 Python 3 之前的版本,我无法为您提供帮助,但我在以下方面取得了非常好的成功:

import pandas as pd
from contextlib import redirect_stderr
import io

# Redirect stderr to something we can report on.
f = io.StringIO()
with redirect_stderr(f):
    df = pd.read_csv(
        new_file_name, header=None, error_bad_lines=False, warn_bad_lines=True, dtype=header_types
    )
if f.getvalue():
    logger.warning("Had parsing errors: {}".format(f.getvalue()))

我多次搜索这个问题并不断被指向这个问题。希望以后对其他人有所帮助。

【讨论】:

  • 你能定义logger吗?
  • 发布了编辑。 @scottlittle,将 logger.warning 替换为 print
猜你喜欢
  • 2018-05-02
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-24
  • 2013-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多