我有一个非常大的数据帧(数千x)只显示5 x 3这里,时间是索引
pd.read_csv(filename)
由于这些来自其他设备(df由float
生成),因此数据框而不是完全+unend
类型现在最终会出现不需要的字符串,例如n. def.
和{{ 1}}。这些不是经典的+infinity
或NaN
,df.fillna()
可以解决这些问题。我想用0.0
替换字符串。我看到了这些答案Pandas replace type issue和replace string in pandas dataframe虽然尝试做同样的事情,但是列或行是明智的,但不是元素。但是,在评论中,对于一般情况也有一些很好的提示。
如果我尝试
mask = df.apply(lambda x: x.str.contains(r'+unend|n. def.'))
df[mask] =0.0
我得到error: nothing to repeat
如果我这样做
mask = df.apply(lambda x: (str('n. def.') in (str(x)) or (str('unend') in str(x))) )
df[mask]=0.0
我会为每个列而不是元素掩码获得一个True或False的Series对象,因此会出错
TypeError: Cannot do inplace boolean setting on mixed-types with a non np.nan value
。
以下
mask = df.applymap(lambda x: (str('n. def.') in (str(x)) or (str('unend') in str(x))) )
df[mask.values]=0.0
确实给了我预期的结果用0.0替换所有不需要的字符串但是,它很慢(unpythonic?)而且,我不确定我是否可以使用正则表达式进行检查而不是in
,尤其是如果我知道有混合数据类型。有没有一种高效,快速,强大但也是元素的一般方法来做到这一点?
答案 0 :(得分:5)
这些不是经典的+无穷大或NaN,df.fillna()可以解决这个问题
您可以在阅读csv文件时指定要考虑为NA
的字符串列表。
df = pd.read_csv(filename, na_values=['+unend', 'n. def.'])
然后使用NA
fillna
值
答案 1 :(得分:0)
如所指示Edchum
,如果需要将所有非数字值替换为0
- 首先to_numeric
errors='coerce'
创建NaN
s表示不可解析的值,然后转换他们0
到fillna
:
df = df.apply(lambda x: pd.to_numeric(x, errors='coerce')).fillna(0)
如果值不是substring
使用DataFrame.isin
或非常好的Haleemur Ali答案:
df = df.mask(df.isin(['+unend','n. def.']), 0).astype(float)
对于具有定义值的substrings
:
有特殊的正则表达式字符+
和.
,因此需要通过\
转义它们:
df = df.mask(df.astype(str).apply(lambda x: x.str.contains(r'(\+unend|n\. def\.)')), 0).astype(float)
或使用applymap
进行elemnetwise检查:
df = df.mask(df.applymap(lambda x: (str('n. def.') in (str(x)) or (str('unend') in str(x))) ), 0).astype(float)
print (df)
col1 col2 col3
time
05/04/2018 05:14:52 AM 0.000 0.0 0.000
05/04/2018 05:14:57 AM 0.000 0.0 0.000
05/04/2018 05:15:02 AM 30.691 0.0 0.121
05/04/2018 05:15:07 AM 30.691 0.0 0.108
05/04/2018 05:15:12 AM 30.715 0.0 0.105
答案 2 :(得分:0)
请勿使用pd.Series.str.contains或pd.Series.isin
解决此问题的更有效方法是使用pd.to_numeric
转换try并将所有数据转换为数字。
使用errors='coerce'
默认为NaN
,然后您可以使用pd.Series.fillna
。
cols = ['col1', 'col2', 'col3']
df[cols] = df[cols].apply(pd.to_numeric, errors='coerce').fillna(0)