我有一个包含多个列的CSV文件,其中包含整数和字符串。当然,由于混合dtypes,我得到了dtype警告。我用这个通用命令读取文件。
df = pd.read_csv(path, sep=";", na_values=missing)
我可以使用low_memory=False
或dtype=object
来消除警告,但据我所知,这使得阅读我的文件的内存效率更高。
我也可以使用na_values="my_string"
,但我有其他缺失值(应该是真正的缺失值)并且不想混合它们。
我不需要字符串的值,只需要它的值计数,所以我想用一个整数替换它。这样的事情。
df.replace(to_replace="my_string", value=999)
但是,还可以在读取CSV文件时替换值吗?还是存在另一种解决方案?我不想简单地使警告静音,而是找到一种更节省内存的解决方案。
(我知道this answer,但它对我的问题没有任何帮助。)
答案 0 :(得分:3)
您可以使用converters:
In [156]: def conv(val, default_val=999):
...: try:
...: return int(val)
...: except ValueError:
...: return default_val
...:
In [157]: conv('a')
Out[157]: 999
In [158]: pd.read_csv(r'C:\Temp\test.csv', converters={'a':conv})
Out[158]:
a b c
0 1 11 2000-01-01
1 999 12 2000-01-02
2 3 13 2000-01-02
另一种方法是在解析CSV文件后以矢量化方式转换列:
In [166]: df = pd.read_csv(r'C:\Temp\test.csv', parse_dates=['c'])
In [167]: df
Out[167]:
a b c
0 1 AAA 2000-01-01
1 XXX 12 2000-01-02
2 3 13 2000-01-02
In [168]: df.dtypes
Out[168]:
a object
b object
c datetime64[ns]
dtype: object
In [169]: int_cols = ['a','b']
In [170]: df[int_cols] = df[int_cols].apply(pd.to_numeric, errors='coerce').fillna(999).astype(int)
In [171]: df
Out[171]:
a b c
0 1 999 2000-01-01
1 999 12 2000-01-02
2 3 13 2000-01-02
In [172]: df.dtypes
Out[172]:
a int32
b int32
c datetime64[ns]
dtype: object
300.000行的速度比较DF:
In [175]: df = pd.concat([df] * 10**5, ignore_index=True)
In [176]: df.shape
Out[176]: (300000, 3)
In [177]: filename = r'C:\Temp\test.csv'
In [184]: df.to_csv(filename, index=False)
In [185]: %%timeit
...: df = pd.read_csv(filename, parse_dates=['c'], converters={'a':conv, 'b':conv})
...:
632 ms ± 25.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [186]: %%timeit
...: df = pd.read_csv(filename, parse_dates=['c'])
...: df[int_cols] = df[int_cols].apply(pd.to_numeric, errors='coerce').fillna(999).astype(int)
...:
706 ms ± 60.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
答案 1 :(得分:1)
在阅读CSV文件时无法替换de值。加载数据并保存后,必须更换。然后你不再收到警告了。