【问题标题】:python - find index of last two numbers in a mixed type list [closed]python - 在混合类型列表中查找最后两个数字的索引[关闭]
【发布时间】:2018-11-18 23:04:29
【问题描述】:

我有以下带有数字和 nan 的列表:

test_list = [1, 2, 3, np.nan, 4, np.nan, 4.3, 4.5, np.nan, np.nan]

如何找到最后一个连续数字停止的索引?对于 test_list,代码将返回 7。

感谢您的回复

编辑 - 很抱歉没有把它放在那里。罗里,感谢您澄清我的问题所在。

import numbers
import numpy as np

test_list = [1, 2, 3, np.nan, 4, np.nan, 4.3, 4.5, np.nan, np.nan]

streak = 0
streak_list = list()
for t in test_list:
    if isinstance(t, numbers.Number) and ~np.isnan(t):
        streak += 1
    else:
        streak = 0
    streak_list.append(streak)

此循环产生以下输出:

[1, 2, 3, 0, 1, 0, 1, 2, 0, 0]

那我试过这个,在一个小测试中是正确的,但我不是100%有信心。

streak_ends = [i for i, e in enumerate(streak_list) if e >= 2]
answer = streak_ends[-1]

我不仅认为总体上可能有更好的方法来执行此操作,而且我认为这在海量数据集上会相当慢。似乎有一种更简洁的方法可以找到它。

【问题讨论】:

  • for... if... 平常的东西...
  • 假设您自己不付出任何努力就可以得到响应是冒昧的。
  • 好的,所以我真的不确定如何解决这个问题。我尝试过的东西就像它不起作用一样不符合pythonic。如果我不清楚,我的意思是问如何找到最后一个数字类型的列表元素的索引,该元素前面也是数字类型。
  • @fmc100。您应该在问题中非常清楚地说明这一点,也许通过提供一些输入示例,其中最后一个整数是单独的。另外,请展示您迄今为止所做的任何尝试。他们不必成功。你只需要解释出了什么问题。
  • 这样更好吗?必须是更好的方法来做到这一点......

标签: python list numpy


【解决方案1】:

您可以使用以下两个提示来编写代码。

首先,您可以通过测试表达式来检查给定的 Python 值 val 是否为“正数”

isinstance(val, numbers.Number) and cmath.isfinite(val)

该表达式将是 True 用于常规数字,False 用于其他值。当然,对于标准模块numberscmath,这必须以import 语句开头。对于技术 Python 数字但不属于复数的稀有类型,此表达式将出错。我现在想不出任何这样的类型,所以这对你来说应该很好。如果您想防止复杂的数字类型,您可以修改该表达式。

其次,这是一种查看列表、元组或任何迭代器中连续值对的 Python 方法。

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

这来自recipes section of the documentation for itertools。这使用了来自 itertools 的 teeizip 函数,因此您还需要导入这些函数。


由于您添加了自己的代码,因此这里是一种解决方案。此代码试图通过从末尾向后工作并在找到一对连续数字时立即停止来快速处理非常长的列表。这也避免了以正向或反向顺序复制列表。如果原始序列是 Numpy ndarray,则可以使用相反顺序的数组视图来制定更快的例程。但在这里我只是假设一个很长的 Python 列表。

import cmath, numbers

def isnumber(val):
    """Return if a given value is a regular number"""
    return isinstance(val, numbers.Number) and cmath.isfinite(val)

def ndx_consecutive_numbers(asequence):
    """Return the index of the second number in the last pair of
    consecutive numbers in a given sequence. If no such pair of
    consecutive numbers exists, return -1."""
    prev_was_number = False
    for ndx in range(len(asequence)-1, -1, -1):
        if not isnumber(asequence[ndx]):
            prev_was_number = False
        elif prev_was_number:
            return ndx + 1
        else:
            prev_was_number = True
    return -1

print(ndx_consecutive_numbers(
        [1, 2, 3, cmath.nan, 4, cmath.nan, 4.3, 4.5, cmath.nan, cmath.nan]))
print(ndx_consecutive_numbers(
        [1, 2, 3, 'a', 4, (5, 6), 4.3, 4.5, cmath.nan, 5, {}]))
print(ndx_consecutive_numbers(
        [3, cmath.nan, 4, cmath.nan, 4.5, cmath.nan, 5, cmath.nan]))

这会产生所需的打印输出,

7
7
-1

【讨论】:

  • 您的第一个回复帮助我发现了我如何处理的问题,并提出了一个可行的解决方案,但我仍然认为这是一个糟糕的解决方案。谢谢
【解决方案2】:
out = []
for i in range(len(test_list)):
    if isinstance(test[i-1], int) or isinstance(test[i-1], float):
        out += test[i-1]
print('Consecutive numbers stop at index: '+test_list.find(out[len(out)-1])

这应该可行,但在问这样一个简单的问题之前,您需要查看文档或使用 Google。

【讨论】:

  • 您的代码失败,部分原因是您使用了不存在的变量test。还有其他问题。你运行这段代码了吗?另外,我相信您的测试会将naninf 视为OP 显然不想要的“数字”。也许您应该在您的 if 语句中添加一个或两个 isfinite 测试。
猜你喜欢
  • 1970-01-01
  • 2022-11-11
  • 2015-08-29
  • 2021-04-20
  • 2014-06-24
  • 1970-01-01
  • 2022-06-15
  • 2020-09-30
  • 1970-01-01
相关资源
最近更新 更多