【问题标题】:How to subset list elements that lie between two missing values?如何对位于两个缺失值之间的列表元素进行子集化?
【发布时间】:2020-06-19 05:15:15
【问题描述】:

使用包含一些缺失值的列表,例如:

[10, 11, 12,np.nan, 14, np.nan, 16, 17, np.nan, 19, np.nan]

如何对位于两个缺失 (nan) 值之间的值进行子集化?

我知道如何使用 for loop 来做到这一点:

# imports
import numpy as np

# input
lst=[10,11,12,np.nan, 14, np.nan, 16, 17, np.nan, 19, np.nan]

# define an empty list and build on that in a For Loop
subset=[]
for i, elem in enumerate(lst):
    if np.isnan(lst[i-1]) and np.isnan(lst[i+1]):
        subset.extend([elem])

print(subset)

# output
# [14, 19]

关于如何以不那么繁琐的方式执行此操作的任何建议?

【问题讨论】:

  • 你已经在使用枚举,所以你知道索引,它在 i 中,所以只需使用 elem 的那个 instaed
  • @ChrisDoyle 感谢您的回复。我希望列表理解或一些矢量化方法可以加快更大列表的速度
  • 啊,好吧,永恒已经给出了一个列表理解示例
  • 所以对于lst = [1, np.nan],你想要的输出是[1]?
  • 对于lst = [np.nan] 来说崩溃没关系?

标签: python python-3.x list numpy


【解决方案1】:

我是一个 NumPy 菜鸟,所以可能可以做得更好......

>>> a = np.array(lst)
>>> a[1:-1][np.isnan(a[:-2]) & np.isnan(a[2:])]
array([14., 19.])

对于我在 cmets 中的示例 [1, np.nan][np.nan],这会按预期生成一个空数组。

或者正如 Georgy 所说,isnan 只做一次:

>>> a = np.array(lst)
>>> nan = np.isnan(a)
>>> a[1:-1][nan[:-2] & nan[2:]]
array([14., 19.])

正如 kaya3 评论的那样,如果可以连续存在三个 nan,则这些解决方案将在结果中包含中间一个(就像您的原始解决方案一样)。这是一个没有(在测试中我用 nan 替换了 14):

>>> a[1:-1][nan[:-2] & ~nan[1:-1] & nan[2:]]
array([19.])

【讨论】:

  • 你可以做一个小的改进,所以去掉np.isnan(a)的计算,而不是计算两次。
  • 如果有 3 个或更多 NaN 值的序列,您可以添加一个 & nan[1:-1] 术语。
  • @kaya3 嗯,是的,应该检查一下。尽管 OP 在他们的 "我知道如何使用 for 循环" 参考解决方案中也没有这样做,但它可能不会发生或需要获得 nan。或者这可能是他们忽略的另一件事:-)。我会补充的。
【解决方案2】:

你可以使用内置函数zip

subset = [e2 for e1, e2, e3 in zip(lst, lst[1:], lst[2:]) if np.isnan(e1) and not np.isnan(e2) and np.isnan(e3)]
print(subset)

输出:

[14, 19]

【讨论】:

    【解决方案3】:

    使用列表理解

    import numpy as np
    lst=[10,11,12,np.nan, 14, np.nan, 16, 17, np.nan, np.nan, np.nan]
    subset = [elem for i, elem in enumerate(lst) if i and i < len(lst)-1 and np.isnan(lst[i-1]) and np.isnan(lst[i+1]) and not np.isnan(elem)]
    print(subset)
    

    更正了其他贡献者指出的错误。这现在应该适用于所有情况。

    【讨论】:

    • 他想要不同的方法来获得所需的输出
    • 是的,没有经过测试,我已经编辑了答案@HeapOverflow
    • 您的输出包含索引,它不是 OP 所需的输出 + 如果您的倒数第二个元素是 np.nan 您的代码将引发 IndexError
    • 确实,没想到@kederrac
    • 可以使用 pandas isnull() 方法吗?它适用于所有类型
    猜你喜欢
    • 2019-02-21
    • 2014-02-16
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 2015-05-01
    相关资源
    最近更新 更多