gpt4 book ai didi

python - read_csv 获取发生异常的行

转载 作者:行者123 更新时间:2023-11-28 17:03:36 29 4
gpt4 key购买 nike

我尝试用 pandas 分析的 HTTP 日志文件有时会有意外的行。这是我加载数据的方式:

df = pd.read_csv('mylog.log',
sep=r'\s(?=(?:[^"]*"[^"]*")*[^"]*$)(?![^\[]*\])',
engine='python', na_values=['-'], header=None,
usecols=[0, 3, 4, 5, 6, 7, 8,10],
names=['ip', 'time', 'request', 'status', 'size',
'referer','user_agent','req_time'],
converters={'status': int, 'size': int, 'req_time': int})

它适用于我拥有的大部分日志(来自同一台服务器)。但是,在加载一些日志时,会引发异常: 要么

 TypeError: int() argument must be a string, a bytes-like object or a  number, not 'NoneType'

ValueError: invalid literal for int() with base 10: '"GET /agent/10577/bdl HTTP/1.1"'

为了示例,下面是触发第二个异常的行:

22.111.117.229, 22.111.117.229 - - [19/Sep/2018:22:17:40 +0200] "GET /agent/10577/bdl HTTP/1.1" 204 - "-" "okhttp/3.8.0" apibackend.site.fr 429282

为了找到受控行的编号,我使用了以下(非常慢)函数:

def search_error_dichotomy(path):    
borne_inf = 0
log = open(path)
borne_sup = len(log.readlines())
log.close()
while borne_sup - borne_inf>1:
exceded = False
search_index = (borne_inf + borne_sup) // 2
try:
pd.read_csv(path,...,...,nrows=search_index)
except:
exceded = True
if exceded:
borne_sup = search_index
else:
borne_inf = search_index

return search_index

我想要的是这样的:

try:
pd.read_csv(..........................)
except MyError as e:
print(e.row_number)

其中e.row_number是乱行的编号。

提前谢谢你。

解决方案所有功劳都归功于 devssh,他的建议不仅使过程更快,而且让我能够一次获得所有意想不到的线路。这是我所做的:

  1. 加载没有转换器的数据框。

    df = pd.read_csv(path,
    sep=r'\s(?=(?:[^"]*"[^"]*")*[^"]*$)(?![^\[]*\])',
    engine='python', na_values=['-'], header=None,
    usecols=[0, 3, 4, 5, 6, 7, 8,10],
    names=['ip', 'time', 'request', 'status', 'size',
    'referer', 'user_agent', 'req_time'])
  2. 使用 .reset_index() 添加“索引”列。

    df = df.reset_index()
  3. 编写自定义函数(与 apply 一起使用),如果可能则转换为 int,否则保存字典错误行中的条目和“索引”

    wrong_lines = {}
    def convert_int_feedback_index(row,col):
    try:
    ans = int(row[col])
    except:
    wrong_lines[row['index']] = row[col]
    ans = pd.np.nan
    return ans
  4. 对我要转换的列使用应用(例如 col = 'status'、'size' 或 'req_time')

    df[col] = df.apply(convert_int_feedback_index, axis=1, col=col)

最佳答案

您是否尝试过 pd.read_csv(..., nrows=10) 看看它是否适用于 10 行?

也许你不应该使用转换器来指定dtypes
加载 DataFrame,然后将 dtype 应用到像 df["column"] = df["column"].astype(np.int64) 这样的列或像 df["column"这样的自定义函数]=df["column"].apply(lambda x: convert_type(x)) 并在函数 convert_type 中自行处理错误。
最后,通过调用 df.to_csv("preprocessed.csv", headers=True, index=False) 更新 csv。
我认为您无法从 pd.read_csv 本身获取行号。该分隔符本身看起来太复杂了。

或者您可以尝试将 csv 作为单列 DataFrame 读取并使用 df["column"].str.extract 以使用正则表达式提取列。这样您就可以控制如何引发异常或处理错误的默认值。

df.reset_index() 将为您提供行号作为列。这样如果你apply to two columns ,您还将获得行号。它将为您提供带有行号的索引列。将其与应用于多列相结合,您可以自定义所有内容。

关于python - read_csv 获取发生异常的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52686559/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com