我有许多具有相同列标题的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()
参数?
答案 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倍。