Python 将数据帧中的无效值替换为无
在Python中,有没有任何方法可以将Pandas中的值替换为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
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})
@AndyHaydendf.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)