【问题标题】:Randomly remove 'x' elements from a list从列表中随机删除“x”元素
【发布时间】:2017-12-06 14:58:43
【问题描述】:

我想在不改变列表顺序的情况下从列表中随机删除一部分元素。

假设我有一些数据,我想删除其中的 1/4:

data = [1,2,3,4,5,6,7,8,9,10]
n    = len(data) / 4

我在想我需要一个循环来遍历数据并删除随机元素“n”次?所以像:

for i in xrange(n):
    random = np.randint(1,len(data))
    del data[random]

我的问题是,这是最“pythonic”的方式吗?我的列表将有大约 5000 个元素长,我想使用不同的 'n' 值多次执行此操作。

谢谢!

【问题讨论】:

    标签: python list random


    【解决方案1】:

    顺序删除是个坏主意,因为列表中的删除是O(n)。而是做这样的事情:

    def delete_rand_items(items,n):
        to_delete = set(random.sample(range(len(items)),n))
        return [x for i,x in enumerate(items) if not i in to_delete]
    

    【讨论】:

      【解决方案2】:

      你可以像这样使用random.sample

      import random
      
      a = [1,2,3,4,5,6,7,8,9,10]
      
      no_elements_to_delete = len(a) // 4
      no_elements_to_keep = len(a) - no_elements_to_delete
      b = set(random.sample(a, no_elements_to_keep))  # the `if i in b` on the next line would benefit from b being a set for large lists
      b = [i for i in a if i in b]  # you need this to restore the order
      print(len(a))  # 10
      print(b)       # [1, 2, 3, 4, 5, 8, 9, 10]
      print(len(b))  # 8
      

      以上两点。

      1. 您没有在原地修改原始列表,但可以。
      2. 您实际上并没有删除元素,而是保留了元素,但这是一回事(您只需要调整比率)
      3. 缺点是恢复元素顺序的列表理解

      正如@koalo 在 cmets 中所说,如果原始列表中的元素不是唯一的,上述将无法正常工作。我可以很容易地解决这个问题,但我的答案将与@JohnColeman 发布的相同。因此,如果可能是这种情况,请改用他的。

      【讨论】:

      • 谢谢!我实际上想保留“a”中剩下的内容,而不是删除的内容
      • 如果一个元素在数组中出现多次,这将不起作用!
      • 这太棒了!谢谢:)
      【解决方案3】:

      订单有意义吗? 如果没有,您可以执行以下操作:

      shuffle(data)
      data=data[:len(data)-n]
      

      【讨论】:

        【解决方案4】:

        我建议使用 numpy 索引

        import numpy as np
        data = np.array([1,2,3,4,5,6,7,8,9,10])
        n = len(data)/4
        indices = sorted(np.random.choice(len(data),len(data)-n,replace=False))
        result = data[indices]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-02-07
          • 1970-01-01
          • 2018-07-19
          • 2014-03-06
          • 2016-05-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多