如何在不知道NA值模式的情况下快速将列转换为数字

时间:2015-06-26 01:39:21

标签: csv pandas

我有许多具有相同列标题的CSV文件要解析。在这些文件中,可能有几种模式来表示NA,例如:“ - ”,“ - ”,“/”,......

我不知道所有模式,所以我无法正确设置na_values的{​​{1}}参数。

有没有快速的方法来查找这些文件中的所有NA模式,或者不知道所有模式,我仍然可以将所有列转换为数字?这是我试过的:

read_csv()

但是patterns = set() for i, fn in enumerate(glob(u"data/*.csv")): df = pd.read_csv(fn, encoding="utf-8-sig", usecols=cols, dtype=str, keep_default_na=False) df_num = df.convert_objects(convert_numeric=True) patterns.update( df[df_num.isnull()].stack().value_counts().index ) 很慢。这是一些测试:

  • convert_objects():约2.2s
  • read_csv(dtype=str)没有read_csv()参数:约2.5s
  • dtype + read_csv(dtype=str):8.4s

因此,convert_objects()可以非常快地将字符串转换为数字read_csv()。但是如果有一个元素无法转换为数字,则整个列将成为字符串列。

是否有更快的方法可以将所有列转换为数字而不设置convert_objects()参数?

2 个答案:

答案 0 :(得分:0)

为什么不直接将'index_col'参数设置为False。这将导致pandas从零开始按顺序对列进行编号我相信。以下是您的代码在更改时的样子:

patterns = set()
for i, fn in enumerate(glob(u"data/*.csv")):
    df = pd.read_csv(fn, encoding="utf-8-sig", index_col=False, usecols=cols, dtype=str, keep_default_na=False)
    df_num = df.convert_objects(convert_numeric=True)
    patterns.update( df[df_num.isnull()].stack().value_counts().index )

答案 1 :(得分:0)

如果您有pandas版本> = 0.17.0,您可以尝试为每列应用pandas.to_numeric(或者您可能知道可疑列):

import pandas as pd

df = pd.DataFrame({'a':[1, 2, 3, 4, 'b', 'a', 6], 'b':[0, 1, 2, 'a', 3, 4, 'b']}, dtype=str)

一些基准测试:

In [78]: %timeit df.convert_objects(convert_numeric=True)
1000 loops, best of 3: 480 µs per loop

In [79]: %timeit df.apply(pd.to_numeric, errors='coerce')
1000 loops, best of 3: 880 µs per loop

我们可以看到它比convert_object慢。让我们通过raw=True apply

In [82]: %timeit df.apply(pd.to_numeric, raw=True, errors='coerce')
1000 loops, best of 3: 288 µs per loop

现在它的速度比convert_objects快近2倍。