如何在Python中的Pandas数据框中用None替换值?

Bla*_*ard 68 python replace nan dataframe pandas

是否有任何方法可以None在Python 中用Pandas 替换值?

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

所以这是一个例子:

df = DataFrame(['-',3,2,5,1,-5,-1,'-',9])
df.replace('-', 0)
Run Code Online (Sandbox Code Playgroud)

返回成功的结果.

但,

df.replace('-', None)
Run Code Online (Sandbox Code Playgroud)

返回以下结果:

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
Run Code Online (Sandbox Code Playgroud)

为什么会返回这么奇怪的结果?

由于我想将这个数据帧倒入MySQL数据库,因此我无法将NaN值放入数据框中的任何元素中,而是想放入None.当然,您可以先更改'-'NaN然后转换NaNNone,但我想知道为什么数据框以这种可怕的方式运行.

And*_*den 92

实际上在更高版本的pandas中,这会产生一个TypeError:

df.replace('-', None)
TypeError: If "to_replace" and "value" are both None then regex must be a mapping
Run Code Online (Sandbox Code Playgroud)

您可以通过传递列表或字典来完成:

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
Run Code Online (Sandbox Code Playgroud)

但我建议使用NaN而不是None:

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
Run Code Online (Sandbox Code Playgroud)

  • 或者只是一个列表,例如`df.replace([' - '],[None])`或`df.replace({' - ':None})`,我想.使用"无"作为哨兵也不能将其用作值. (11认同)
  • 我不知道它是否显而易见,但不得不将`df`分配给自己,如:`df = df.replace({'?':np.nan})` (3认同)
  • @AndyHayden`df.replace('-',df.replace(['-'],[None])`看起来很时髦,是错字吗? (2认同)
  • @lin_bug 虽然它似乎不再适用于最近的熊猫版本。df.where(df!='-', None) 有效 (2认同)

小智 14

where可能就是你要找的东西.所以

data=data.where(data=='-', None) 
Run Code Online (Sandbox Code Playgroud)

来自熊猫文档:

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

  • 这实际上是不准确的.data = data.where(data ==' - ',None)将使用None替换与' - '不等的任何内容.Pandas版本的where保留第一个arg的值(在本例中为data ==' - '),并用第二个arg替换其他任何东西(在本例中为None).这有点令人困惑,因为np.where更明确的是它在第一个arg中询问条件,然后在第二个arg中if if,然后在第3个arg中if if. (5认同)

Mic*_*ner 12

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

df.replace({'-': None})
Run Code Online (Sandbox Code Playgroud)

您还可以拥有更多替代品:

df.replace({'-': None, 'None': None})
Run Code Online (Sandbox Code Playgroud)

即使对于更大的替代品,在我看来,总是显而易见并清楚什么被什么取代 - 这对于长列表来说更难.

  • 值得注意的是,该技术有效的部分原因是在“to_replace”中使用“dict”类型会导致“method”参数无法被评估,因此“method='pad”默认没有任何问题。影响。 (2认同)

cs9*_*s95 10

在继续这篇文章之前,了解NaN 和 None 之间的区别很重要。一种是浮点类型,另一种是对象类型。Pandas 更适合处理标量类型,因为这些类型的许多方法都可以向量化。Pandas 确实尝试一致地处理 None 和 NaN,但 NumPy 不能。

我的建议(和 Andy 的)是坚持使用 NaN。

但是要回答你的问题...

熊猫 >= 0.18:使用na_values=['-']参数read_csv

如果您从 CSV/Excel 加载此数据,我有好消息要告诉您。您可以在数据加载期间在根处取消此设置,而不必在后续步骤中使用代码编写修复程序。

大多数pd.read_*函数(例如read_csvread_excel)都接受一个na_values属性。

file.csv

A,B
-,1
3,-
2,-
5,3
1,-2
-5,4
-1,-1
-,0
9,0
Run Code Online (Sandbox Code Playgroud)

现在,要将-字符转换为 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
Run Code Online (Sandbox Code Playgroud)

其他功能/文件格式也类似。

PS:在 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
Run Code Online (Sandbox Code Playgroud)

dtype 不是传统的 int 类型……而是一个Nullable Integer 类型。还有其他选择。


处理数字数据:pd.to_numericerrors='coerce

如果你正在处理的数字数据,更快的解决方案是使用pd.to_numericerrors='coerce'参数,它强制转换无效值(值不能转换为数字)为NaN。

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

0    NaN
1    3.0
2    2.0
3    5.0
4    1.0
5   -5.0
6   -1.0
7    NaN
8    9.0
Name: A, dtype: float64
Run Code Online (Sandbox Code Playgroud)

要保留(可为空)整数 dtype,请使用

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 
Run Code Online (Sandbox Code Playgroud)

要强制多列,请使用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
Run Code Online (Sandbox Code Playgroud)

...并在之后分配结果。

更多信息可以在这个答案中找到。


Acu*_*nus 8

对于 Pandas 版本 \xe2\x89\xa51.0.0,我将使用DataFrame.replaceor Series.replace

\n
df.replace(old_val, pd.NA, inplace=True)\n
Run Code Online (Sandbox Code Playgroud)\n

这样做更好有两个原因:

\n
    \n
  1. 它使用pd.NA代替Nonenp.nan
  2. \n
  3. 它可以选择就地工作,这可以提高内存效率,具体取决于内部实现。
  4. \n
\n