Python pandas系列:将浮点数转换为字符串,保留空值。

17

在转换为字符串后,我如何保留空值?我正在处理社会安全号码,在其中需要在浮点型和字符串之间来回切换。

import pandas as pd
import numpy as np    
x = pd.Series([np.nan, 123., np.nan, 456.], dtype = float)
x.isnull()

...存在空值

y = x.astype(str)
y.isnull()

...没有空值

理想情况下,x.isnull()和y.isnull()应该是相同的。

我认为使用混合数据类型的系列很危险,但暂时认为这是最佳解决方案:

z = y.copy()
z[z == 'nan'] = np.nan
z.isnull() # works as desired
type(z[0]) # but has floats for nulls
type(z[1]) # and strings for values
6个回答

13

我也遇到过这个问题,但是针对DataFrames。一个适用于pandas Series和DataFrame的方法是利用mask():

data = pd.Series([np.NaN, 10, 30, np.NaN]) # Also works for pd.DataFrame
null_cells = data.isnull()
data = data.astype(str).mask(null_cells, np.NaN)

我喜欢这个解决方案。对于我的混合数据类型数据集表现良好。谢谢。 - Aaron England

11

1
这个应该是最佳答案,因为这是最简单、最具有“pandas解决问题”的方式。 - Sam
1
我在使用这个解决方案时遇到的问题是,当我尝试将所有的空值保存到数据库时,它们都被转换为"<NA>"。 - Chris
所以现在我有一些包含None值的对象(str)列和一些包含<Na>(<class 'pandas._libs.missing.NAType'>)值的对象(Str)列,为什么它们不能只接受None作为唯一的NA/NaN/NaI/NaD值呢...我认为最受欢迎的答案在这方面更好,因为它允许您自己设置所需的"None"值。 - undefined

6
你可以将其转换为字符串,前提是不为null。
x[x.notnull()] = x.astype(str)

x
Out[32]
0      NaN
1    123.0
2      NaN
3    456.0
dtype: object

x.values
Out[33]: array([nan, '123.0', nan, '456.0'], dtype=object)

x.isnull()
Out[34]
0     True
1    False
2     True
3    False
dtype: bool

如果你将分类变量(int)转换为分类变量(str),这个方法是行不通的。正确的做法是:x[c.notnull()] = x[c.notnull()].astype(str) - undefined

2

如果你将 np.nan 转换为 str,它就会变成字符串 'nan',并且会像其他字符串一样被 isnull 处理。

关于你的编辑:在将值转换为字符串后,你需要定义哪些字符串在你看来是“null”。一种方法是:

y.isin(['nan', '0', '']) # list contains whatever you want to be evaluated as null

这样至少可以得到您想要的结果。

我认为,您不能使用 isnull 来实现此目的,但是您可以编写自己的方法,查找您认为为 null 的所有字符串值。 - Arco Bast
1
明白了。似乎拥有一个对象数据类型的系列,除了空值之外都是字符,这看起来有些可疑,但我认为这是最好的选择。 - mef jons
我的回答中是否有什么遗漏或不清楚的地方?如果没有,也许您可以将其标记为已接受? - Arco Bast
这很好,但在可能的情况下,我更喜欢使用预构建的 pandas 方法。只要我小心地设置了一切,混合数据类型是我可以在我的工作中忘记的事情,但是不同的查找NA的方式会让我感到繁琐。 - mef jons
只是好奇,你为什么首先要转换成字符串? - Arco Bast
显示剩余2条评论

1
使用series.where()函数仅将非空值转换为字符串:
y = x.where(x.isnull(), x.astype(str))
y.isnull()

0
由于某些原因,当您使用Series.astype(str)转换系列时,np.NaN会被转换为字符串'nan',但是在使用dtype=str创建新系列时不会。因此,以下操作将起作用:
x_str = pd.Series([np.nan, 123., np.nan, 456.], dtype = str)
x_str.isnull() # Has nulls as expected

了解这一点后,我们可以使用Series构造函数将现有的系列转换为字符串,同时保留空值:

x = pd.Series([np.nan, 123., np.nan, 456.], dtype = float)
x.isnull() 
y1 = pd.Series(x.array, dtype=str)
y1.isnull() # Has nulls as expected

请注意,为了使此功能正常工作,您需要将数组或列表传递给Series构造函数(在当前示例中,这意味着调用x.arrayx.values)。如果您传递了一个Series,则空值将被转换,就好像您调用了astype()一样。

y2 = pd.Series(x, dtype=str)  # x is a series
y2.isnull()  # Nulls converted to 'nan'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接