Python 将数据帧中的无效值替换为无

Python 将数据帧中的无效值替换为无,python,pandas,dataframe,replace,nan,Python,Pandas,Dataframe,Replace,Nan,在Python中,有没有任何方法可以将Pandas中的值替换为None 您可以使用df.replace('pre','post')并可以用另一个值替换一个值,但是如果您想用None值替换,则无法完成此操作,如果您尝试,会得到奇怪的结果 下面是一个例子: df = DataFrame(['-',3,2,5,1,-5,-1,'-',9]) df.replace('-', 0) 返回一个成功的结果 但是, 返回以下结果: 0 0 - // this isn't replaced 1 3 2

在Python中,有没有任何方法可以将Pandas中的值替换为
None

您可以使用
df.replace('pre','post')
并可以用另一个值替换一个值,但是如果您想用
None
值替换,则无法完成此操作,如果您尝试,会得到奇怪的结果

下面是一个例子:

df = DataFrame(['-',3,2,5,1,-5,-1,'-',9])
df.replace('-', 0)
返回一个成功的结果

但是,

返回以下结果:

0
0   - // this isn't replaced
1   3
2   2
3   5
4   1
5  -5
6  -1
7  -1 // this is changed to `-1`...
8   9
为什么会返回如此奇怪的结果

因为我想将这个数据框放入MySQL数据库,所以我不能将
NaN
值放入数据框中的任何元素,而是希望将
None
放入其中。当然,您可以先将
'-'
更改为
NaN
,然后将
NaN
转换为
None
,但我想知道为什么数据帧的行为如此糟糕

在Python2.7和OSX10.8上的pandas 0.12.0 dev上测试。Python是一种 OS X上的预装版,我使用SciPy安装了pandas 超级打包脚本,供您参考


实际上,在熊猫的后续版本中,这将产生一个类型错误:

df.replace('-', None)
TypeError: If "to_replace" and "value" are both None then regex must be a mapping
您可以通过传递列表或字典来执行此操作:

In [11]: df.replace('-', df.replace(['-'], [None]) # or .replace('-', {0: None})
Out[11]:
      0
0  None
1     3
2     2
3     5
4     1
5    -5
6    -1
7  None
8     9
但我建议使用NAN,而不是不使用:

In [12]: df.replace('-', np.nan)
Out[12]:
     0
0  NaN
1    3
2    2
3    5
4    1
5   -5
6   -1
7  NaN
8    9

其中
可能就是您要查找的内容。所以

data=data.where(data=='-', None) 
从:

其中
[返回]与self形状相同的对象,其对应条目来自self,其中cond为True,否则来自other)


我更喜欢使用
dict
的解决方案,因为它简单而优雅:

df.replace({'-': None})
您还可以进行更多替换:

df.replace({'-': None, 'None': None})

即使对于较大的替换,用什么替换什么总是显而易见的,在我看来,这对于长列表来说要困难得多。

设置空值可以使用
np.nan

df = pd.DataFrame(['-',3,2,5,1,-5,-1,'-',9])
df = df.where(df!='-', None)
import numpy as np
df.replace('-', np.nan)

优点是,
df.last\u valid\u index()
识别出这些是无效的。

在继续写这篇文章之前,理解这一点很重要。一个是浮动类型,另一个是对象类型。Pandas更适合使用标量类型,因为这些类型上的许多方法都可以矢量化。熊猫确实试图始终如一地处理None和NaN,但NumPy不能

我的建议()是坚持南

但要回答你的问题

pandas>=0.18:将
na_值=['-']
参数与
read_csv
如果您从CSV/Excel加载此数据,我有好消息要告诉您。在数据加载过程中,您可以在根目录下取消此操作,而无需在后续步骤中使用代码编写修复程序

大多数
pd.read.*
函数(如and)都接受
na_值属性

file.csv

A,B
-,1
3,-
2,-
5,3
1,-2
-5,4
-1,-1
-,0
9,0
现在,要将
-
字符转换为NaN,请执行以下操作:

import pandas as pd
df = pd.read_csv('file.csv', na_values=['-'])
df

     A    B
0  NaN  1.0
1  3.0  NaN
2  2.0  NaN
3  5.0  3.0
4  1.0 -2.0
5 -5.0  4.0
6 -1.0 -1.0
7  NaN  0.0
8  9.0  0.0
和其他函数/文件格式类似

附言:在v0.24+上,即使你的列有NaN,你也可以保留整数类型(是的,谈论吃蛋糕和吃蛋糕)。您可以指定
dtype='Int32'

df = pd.read_csv('file.csv', na_values=['-'], dtype='Int32')
df

     A    B
0  NaN    1
1    3  NaN
2    2  NaN
3    5    3
4    1   -2
5   -5    4
6   -1   -1
7  NaN    0
8    9    0

df.dtypes

A    Int32
B    Int32
dtype: object
数据类型不是常规的int类型。。。但事实上,还有其他选择


处理数字数据:
pd.\u Numeric
带有
errors='concurve
如果您处理的是数字数据,一个更快的解决方案是使用
errors='concurve'
参数,该参数将无效值(无法转换为数字的值)强制为NaN

要保留(可为空)整数数据类型,请使用

pd.to_numeric(df['A'], errors='coerce').astype('Int32')

0    NaN
1      3
2      2
3      5
4      1
5     -5
6     -1
7    NaN
8      9
Name: A, dtype: Int32 
要强制多个列,请使用
apply

df[['A', 'B']].apply(pd.to_numeric, errors='coerce').astype('Int32')

     A    B
0  NaN    1
1    3  NaN
2    2  NaN
3    5    3
4    1   -2
5   -5    4
6   -1   -1
7  NaN    0
8    9    0
…然后将结果分配回


有关更多信息,请参见。

使用替换并分配新df:

import pandas as pd
df = pd.DataFrame(['-',3,2,5,1,-5,-1,'-',9])
dfnew = df.replace('-', 0)
print(dfnew)


(venv) D:\assets>py teste2.py
   0
0  0
1  3
2  2
3  5
4  1
5 -5

这将确保您可以在以后的数据帧上使用带有Pandas版本的
isnull()≥1.0.0,我将使用或:

这样做比较好,有两个原因:

  • 它使用而不是
    None
    np.nan
  • 它替换了可以更高效地使用内存的值

  • 或者仅仅是一个列表,例如,
    df.replace(['-'],[None])
    ,或者
    df.replace({'-':None})
    ,我想。使用
    None
    作为一个哨兵,也就排除了使用它作为一个值的可能性。@user2360798 replace实际上是一个功能非常丰富(读起来很复杂)的函数,但是它确实很好。我不知道它是否明显,但必须将
    df
    重新分配给它自己,比如:
    df=df.replace({'?':np.nan})
    @AndyHayden
    df.replace('-',df.replace(['-'],[None])
    看起来很怪,这是打字错误吗?@lin_bug,尽管在最近的熊猫版本中它似乎不再有效。df.where(df!='-',None)工作
    写入框架
    不解析
    NaN
    s到
    None
    s吗?是的。您遇到
    内部错误:(1054,u“字段列表”中的未知列“NaN”)
    错误。除了在执行
    write\u frame
    方法之前将
    NaN
    转换为
    None
    之外,我不知道有什么其他解决方案。您使用的是什么版本的熊猫?Scipy super pack发布了dev?好的,我肯定认为您应该,应该不太难修复。如果您是从CSV/Excel读取这些数据,哟您可以使用
    na_values
    参数在as NaN中读取这些值。这实际上是不准确的。data=data。其中(data='-',None)将用None替换任何不等于'-'的值。where的版本保留第一个参数的值(在本例中data='-'),并用第二个参数替换任何其他值(在本例中为None)。作为np,这有点令人困惑。where更明确,因为它在第一个参数中询问条件,然后在第二个参数中询问if true,然后在第三个参数中询问if false。值得注意的是,这项技术工作的部分原因是使用
    dict
    键入
    替换
    会导致
    方法
    参数无效因此,
    method='pad'
    默认没有不良影响。
    df[['A', 'B']].apply(pd.to_numeric, errors='coerce').astype('Int32')
    
         A    B
    0  NaN    1
    1    3  NaN
    2    2  NaN
    3    5    3
    4    1   -2
    5   -5    4
    6   -1   -1
    7  NaN    0
    8    9    0
    
    import pandas as pd
    df = pd.DataFrame(['-',3,2,5,1,-5,-1,'-',9])
    dfnew = df.replace('-', 0)
    print(dfnew)
    
    
    (venv) D:\assets>py teste2.py
       0
    0  0
    1  3
    2  2
    3  5
    4  1
    5 -5
    
    df.replace('-', np.nan).astype("object")
    
    df.replace(old_val, pd.NA, inplace=True)