如何将数据框列转换为字符串并替换 nans(fillna 不起作用)

Posted

技术标签:

【中文标题】如何将数据框列转换为字符串并替换 nans(fillna 不起作用)【英文标题】:How to convert a dataframe column to string and replace nans (fillna not working) 【发布时间】:2018-04-12 21:02:19 【问题描述】:

我有一个带有整数列的 pandas 数据框,其中包含一些 nan。我想将它们从整数转换为字符串,并将 nans 替换为“不可用”之类的描述。

主要原因是因为我需要在该列上运行 groupbys,除非我转换 nans,否则 groupby 将摆脱它们!为什么会发生这种情况,以及整个 pandas 社区如何没有站起来,是完全不同的讨论(当我第一次了解它时,我简直不敢相信......)。

我已经尝试了下面的代码,但它不起作用。请注意,我已经尝试过astype(str)astype('str')。在这两种情况下,列都会转换为对象,而不是字符串;可能是因为 Python 假设(错误地,它们在我的数据框中都具有相同的长度)字符串的长度会有所不同?但是,最重要的是,fillna() 不起作用,并且 nans 保持 nans!为什么?

import numpy as np
import pandas as pd

df= pd.DataFrame(np.random.randint(1,10,(10000,5)), columns=['a','b','c','d','e'])
df.iloc[0,0]=np.nan
df['a']=df['a'].astype(str)
df['a']=df['a'].fillna('not available')
print(df.dtypes)
print(df.head())

【问题讨论】:

字符串存储在 dtype 对象中,您无法更改。 . 哦,我的###@@@!!!## ...我刚刚注意到,如果我执行 astype(object),则 fillna 有效。但为什么在地球上? astype(str) 确实已经将其转换为对象。我不明白! 添加您使用的熊猫版本。这对我来说很好。 我使用的是熊猫 0.20.1 astype(str) 是这里的罪魁祸首。它在下面的答案中提到。 【参考方案1】:

fillna 将这些值转换为“str”后将不起作用,该列中不再有 np.nan,而是字符串值“nan”:

df= pd.DataFrame(np.random.randint(1,10,(10000,5)), columns=['a','b','c','d','e'])
df.iloc[0,0]=np.nan
#df['a']=df['a'].astype(str) <-- You don't need this line.
df['a']=df['a'].fillna('not available')
print(df.dtypes)
print(df.head())

输出:

a    object
b     int32
c     int32
d     int32
e     int32
dtype: object
               a  b  c  d  e
0  not available  6  3  9  7
1              5  4  5  5  3
2              4  2  5  3  2
3              4  9  2  8  3
4              2  6  5  9  1

【讨论】:

哦,是的,我认为 OP 将 .astype(str) 作为选项。所以不要太重视这一点,但答案就在那里。 2个问题:1)为什么fillna在转换为字符串后不起作用? 2) 我那习惯于 SQL 的小大脑已经习惯了有字符串、数字、日期等列。它不明白为什么不能将数字转换为字符串,也不明白“对象”到底是什么。 .. fillna 用于填充floating nans 而不是字符串。 @Pythonistaan​​onymous 你首先有一个真正的 np.nan,然后当你转换为字符串时,该值将转换为 'nan' 字符串。因此,该值不再是 np.nan 而是字符串 'nan',因此 fillna 不会替换该字符串。 Pandas 将所有字符串视为数据类型对象。 字符串列可以有一个nan(相当于SQL中的NULL),还是一个字符串只有'nan'?【参考方案2】:
df= pd.DataFrame(np.random.randint(1,10,(10,5)), columns=['a','b','c','d','e'])
df.iloc[0,0]=np.nan

df.isnull()
Out[329]: 
       a      b      c      d      e
0   True  False  False  False  False
1  False  False  False  False  False
2  False  False  False  False  False
3  False  False  False  False  False
4  False  False  False  False  False
5  False  False  False  False  False
6  False  False  False  False  False
7  False  False  False  False  False
8  False  False  False  False  False
9  False  False  False  False  False

你改成str之后

df['a']=df['a'].astype(str)

df.isnull()
Out[332]: 
       a      b      c      d      e
0  False  False  False  False  False
1  False  False  False  False  False
2  False  False  False  False  False
3  False  False  False  False  False
4  False  False  False  False  False
5  False  False  False  False  False
6  False  False  False  False  False
7  False  False  False  False  False
8  False  False  False  False  False
9  False  False  False  False  False

您将空值 np.nan 更改为字符串 'nan'

df.iloc[0,0]
Out[334]: 'nan'

【讨论】:

以上是关于如何将数据框列转换为字符串并替换 nans(fillna 不起作用)的主要内容,如果未能解决你的问题,请参考以下文章

当我在数据框列中有 NaN 时,如何将推文(对象)添加到绘图图表中?

熊猫数据框列有带逗号的字符串如何将其转换为列表[关闭]

使用R函数将数据框列中的字符串替换为“”

将列表转换为pyspark中的数据框列

将 pandas 数据框列从十六进制字符串转换为 int

如何在熊猫数据框列中获取 NaN 观察的频率 [重复]