如何从 dtype 为列表的 Pandas 系列中删除 NaN?
Posted
技术标签:
【中文标题】如何从 dtype 为列表的 Pandas 系列中删除 NaN?【英文标题】:How to remove NaN from a Pandas Series where the dtype is a list? 【发布时间】:2017-05-18 08:46:29 【问题描述】:我有一个pandas.Series
,其中每行的 dtype 是一个列表对象。例如
>>> import numpy as np
>>> import pandas as pd
>>> x = pd.Series([[1,2,3], [2,np.nan], [3,4,5,np.nan], [np.nan]])
>>> x
0 [1, 2, 3]
1 [2, nan]
2 [3, 4, 5, nan]
3 [nan]
dtype: object
如何删除每行列表中的nan
?
期望的输出是:
>>> x
0 [1, 2, 3]
1 [2]
2 [3, 4, 5]
3 []
dtype: object
这行得通:
>>> x.apply(lambda y: pd.Series(y).dropna().values.tolist())
0 [1, 2, 3]
1 [2.0]
2 [3.0, 4.0, 5.0]
3 []
dtype: object
有没有比使用 lambda 更简单的方法,将列表转换为系列,删除 NaN
,然后再次将值提取回列表中?
【问题讨论】:
【参考方案1】:您可以使用 list comprehension
和 pandas.notnull
来删除 NaN
值:
print (x.apply(lambda y: [a for a in y if pd.notnull(a)]))
0 [1, 2, 3]
1 [2]
2 [3, 4, 5]
3 []
dtype: object
filter
的另一种解决方案,条件是 v!=v
仅适用于 NaN
:
print (x.apply(lambda a: list(filter(lambda v: v==v, a))))
0 [1, 2, 3]
1 [2]
2 [3, 4, 5]
3 []
dtype: object
感谢DYZ
提供另一个解决方案:
print (x.apply(lambda y: list(filter(np.isfinite, y))))
0 [1, 2, 3]
1 [2]
2 [3, 4, 5]
3 []
dtype: object
【讨论】:
lambda
和if-else
条件应该可以简化为filter
,不是吗?
@jezrael 解决方案只有一个lambda
: x.apply(lambda y: list(filter(np.isfinite, y)))
。
@jezrael 你有很好的熊猫资源吗...你似乎是它的爱好者
如果dtype是pandas.core.series.Series
怎么办【参考方案2】:
带有列表理解的简单numpy
解决方案:
pd.Series([np.array(e)[~np.isnan(e)] for e in x.values])
【讨论】:
以上是关于如何从 dtype 为列表的 Pandas 系列中删除 NaN?的主要内容,如果未能解决你的问题,请参考以下文章
将 pandas 系列的 dtype <- 'datetime64' 转换为 dtype <- 'np.int' 而无需迭代