将列转换为字符串,保留NaN(为None或空白)

时间:2018-12-23 05:19:55

标签: python pandas

我想在列表中格式化一堆数字。最简单的方法是先将其转换为一串字符串。这是我如何执行此操作的示例:

df[col_name].astype('str').tolist()

但是,与此有关的问题是我得到了诸如以下的值:

['12.19', '13.99', '1.00', 'nan', '9.00']

有没有一种方法可以将'nan'值返回为None或空字符串,例如:

['12.19', '13.99', '1.00', None, '9.00']

或者:

['12.19', '13.99', '1.00', '', '9.00']

我将如何做这两个?

7 个答案:

答案 0 :(得分:1)

尝试使用fillna()

df[col_name].fillna('').astype('str').tolist()

答案 1 :(得分:1)

这是一个独特的要求,我相信最好通过列表理解来解决:

df[col_name]
0    12.19
1    13.99
2     1.00
3      NaN
4     9.00
dtype: float64

[str(v_) if pd.notna(v_) else None for v_ in df[col_name]]
# ['12.19', '13.99', '1.0', None, '9.0'] 

如果您希望将值填充为空白,那同样简单:

[str(v_) if pd.notna(v_) else '' for v_ in df[col_name]]
# ['12.19', '13.99', '1.0', '', '9.0'] 

答案 2 :(得分:1)

您可以执行以下操作:

df[col_name].fillna('').astype('str').tolist()

OR

l = df[col_name].astype('str').tolist()

None替换上面创建的列表中的空元素:

list(map(lambda x: float(x) if x else None, l))

答案 3 :(得分:1)

您可以尝试这样。

  

第一种方式:

>>> df[col_name].apply(lambda v: str(v) if str(v) != 'nan' else None).tolist()
['12.19', '13.99', '1.00', None, '9.00']
>>>
>>> df[col_name].apply(lambda v: str(v) if str(v) != 'nan' else '').tolist()
['12.19', '13.99', '1.00', '', '9.00']
>>>
  

第二种方式:

>>> df[col_name].apply(lambda v: str(v) if not pd.isnull(v) else None).tolist()
['12.19', '13.99', '1.00', None, '9.00']
>>>
>>> df[col_name].apply(lambda v: str(v) if not pd.isnull(v) else '').tolist()
['12.19', '13.99', '1.00', '', '9.00']
>>>

这是详细说明。

>>> import pandas as pd
>>> import numpy as np
>>>
>>> df = pd.DataFrame({
... "fullname": ['P Y', 'P T', 'T Y', 'N A', 'P Z'],
... "age": [36, 80, 25, 8, 34],
... "salary": ['12.19', '13.99', '1.00', np.nan, '9.00']
... })
>>>
>>> df
  fullname  age salary
0      P Y   36  12.19
1      P T   80  13.99
2      T Y   25   1.00
3      N A    8    NaN
4      P Z   34   9.00
>>>
>>> # PROBLEM
...
>>> col_name = "salary"
>>> df[col_name].astype("str").tolist()
['12.19', '13.99', '1.00', 'nan', '9.00']
>>>
>>> # SOLUTION
...
>>> df[col_name].apply(lambda v: str(v) if str(v) != 'nan' else None)
0    12.19
1    13.99
2     1.00
3     None
4     9.00
Name: salary, dtype: object
>>>
>>> df[col_name].apply(lambda v: str(v) if str(v) != 'nan' else '')
0    12.19
1    13.99
2     1.00
3
4     9.00
Name: salary, dtype: object
>>>
>>> df[col_name].apply(lambda v: str(v) if str(v) != 'nan' else None).tolist()
['12.19', '13.99', '1.00', None, '9.00']
>>>
>>> df[col_name].apply(lambda v: str(v) if str(v) != 'nan' else '').tolist()
['12.19', '13.99', '1.00', '', '9.00']
>>>
>>> df[col_name].apply(lambda v: str(v) if not pd.isnull(v) else None).tolist()
['12.19', '13.99', '1.00', None, '9.00']
>>>
>>> df[col_name].apply(lambda v: str(v) if not pd.isnull(v) else '').tolist()
['12.19', '13.99', '1.00', '', '9.00']
>>>

答案 4 :(得分:1)

使用df.astype(str, skipna=True),它将跳过所有NA类型。

示例:

import pandas as pd
df=pd.Series([12.19, 13.99, 1.00, None, 9.00])
print(df.astype(str, skipna=True).to_list())
pd.isna(df.astype(str, skipna=True))

输出:

['12.19', '13.99', '1.0', nan, '9.0']
0    False
1    False
2    False
3     True
4    False
dtype: bool

如果您确实需要将其设置为None而不是np.nan,请添加df=df.where(pd.notnull(df), None)

示例:

df=pd.Series([12.19, 13.99, 1.00, None, 9.00])
df=df.astype(str, skipna=True)
df=df.where(pd.notnull(df), None)
print(df.to_list())

输出:

['12.19', '13.99', '1.0', None, '9.0']

注意: 在熊猫1.0版中,skipna参数从.astype()消失了,该问题当前于2020年2月6日开放。

astype(str) / astype_unicode: np.nan converted to "nan" (checknull, skipna)

Series.astype(str, skipna=True) vanished in the 1.0 release

答案 5 :(得分:0)

创建列表后,您可以尝试删除nan值。

true

我对熊猫一无所知,所以这可能不是最好的解决方案。

答案 6 :(得分:0)

.isalpha()将起作用:

l = ['12.19', '13.99', '1.00', 'nan', '9.00']
print([None if i.isalpha() else i for i in l])
  

['12.19','13 .99','1.00',无,'9.00']