【问题标题】:How to find and replace values of an interval in a list?如何在列表中查找和替换间隔的值?
【发布时间】:2020-08-04 06:53:09
【问题描述】:

我有一个这样的列表:

list_1 = [1, 2, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 1, 2, 3, 4, 1]

在此列表中,紧随4 之后的值大于或小于4 本身。更具体地说,较小的值始终是1。从那个1 到下一个1 的间隔值总是小于4

如何查找和替换这样一个区间的值,例如如下:

list_2 = [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 0, 0, 0, nan, nan, nan, nan, nan, nan, nan, 0]

1, 2, 1 被替换,因为第一个 1 就在 4 之后并且小于 4。因此,从第一个 1 到第二个 1 的间隔被替换。

其他值不必是nan,我只是突出显示替换。需要明确的是,如果后面的值大于4,我们将跳过它。

【问题讨论】:

  • 对于不统一的东西,你可能只需要做一个 for 循环
  • 为什么1, 2, 1 会被替换?你能再举几个例子吗? 从那个 1 到下一个 1 的间隔值总是小于 4 意味着你替换了所有范围 [0, 4),对吧?
  • 1, 2, 1 被替换,因为第一个 1 紧随其后且小于 4。因此,从第一个 1 到第二个 1 的间隔被替换。

标签: python pandas list numpy dataframe


【解决方案1】:

作为一个选项:

for i in range(len(list_1)): # looking at all the elements in the list in order.
    if a[i]==4: # if the number with "i" index equals to "4"
        if a[i+1] > 4: # if the number after 4 is greater than 4
            a[i+1] == nan # the number after 4 equals "nan"

【讨论】:

    【解决方案2】:
    list1 = [1, 2, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 1, 2, 3, 4, 1]
    list2 = []
    i = 0
    while i != len(list1):
        if list1[i] == 4:
            list2.append("nan")
            if list1[i+1] > 4:
                list2.append("Superior to 4 after a 4")
                i+=1
            else:
                list2.append("nan")
                i+=1
        else:
            list2.append("nan")
        i += 1
    print(list2)
    

    代码没有优化,但是如果对应的值不优于4,则在4后面加上“nan”,如果是,则在4后面加上“superior to 4”。

    【讨论】:

      【解决方案3】:

      这是我让 numpy 完成大部分繁重工作的尝试,
      不幸的是,我最后确实使用了 for 循环,希望有人可以提出建议并进行编辑以获得更好的解决方案。

      这是代码:

      import numpy as np
      list_1 = np.array([1, 2, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 1, 2, 3, 4, 1])
      
      modified_list_1 = np.append(list_1,1) # to always have a "next 1"
      
      idx_of_4 = np.where(modified_list_1==4)[0]
      idx_of_1 = np.where(modified_list_1==1)[0]
      
      idx_of_4_followed_by_1 = np.intersect1d(idx_of_4, idx_of_1-1)
      
      arr_slice_idx = [(start, np.min(idx_of_1[idx_of_1>(start+1)])) for start in idx_of_4_followed_by_1]
      
      for start,end in arr_slice_idx:
        list_1[start+1:end+1] = 0
      
      print(list_1)
      

      我首先使用np.wherenp.intersect1d 查找4s 的索引,然后是1s,这是矢量化的,应该可以非常快速地工作
      不幸的是,我在这里没有灵感了,为了找到关闭每个范围的“下一个1”,我使用了常规(相当丑陋)的理解。

      然后当我有了开始和结束时,我使用它们对原始数组进行切片并将值设置为0

      【讨论】:

      • 成功了,谢谢。我修改了这个位 [idx_of_1>=(start+1)] 以说明最后一个元素是 4 的情况。
      • 事实上它应该和原来的解决方案一样,即[idx_of_1>(start+1)],这样第二个元素就是下一个1ValueError pass 将解决最后一个元素为 4 的问题。
      猜你喜欢
      • 1970-01-01
      • 2016-12-05
      • 1970-01-01
      • 2020-06-07
      • 2020-01-10
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 2020-05-25
      相关资源
      最近更新 更多