【问题标题】:Removing items in an array in arbitrary multiples以任意倍数删除数组中的项目
【发布时间】:2017-11-26 22:09:54
【问题描述】:

我有一个数组,它是一个时间列表(它是 10 年的天数),我想删除这个列表的某个选择,然后根据剩余的天数执行计算。这是为了天体物理模拟,我正在尝试选择某些“观察”另一个数据集的模式。

我的数组是:

t = [0,1,2,3,...,3650]

出于我的目的,我想保留每年的前 180 天,并删除其余的天,留下如下内容:

t_new = [1,2,...,178,179,365,366,...]

我通过以下方式实现了这一目标:

a = 180
b = 365 - a

t_new = [x for i, x in enumerate(t) if i%(a+b) < a]

将 a 和 b 作为变量让我能够保持每年不同数量的数据。

现在我想做的是保留每 30 个剩余数据中的前 10 个。这将模拟只能在每个月的前 10 天和每年的前 6 个月进行观察。

我试过了:

c = 10
d = 30-c

t_new2 = [x for i, x in enumerate(t_new) if i%(c+d) < c]

这应该会导致:

t_new2 = [0,1,2,3,4,5,6,7,8,9,30,31,...,178,179,365,366,...]

所以这是我们删除每 30 天中的最后 20 天(每月)和 365 天中的最后 185 天(每年)之后的剩余天数。

但我得到了错误:

ValueError: too many values to unpack

有没有更好的方法来做这个逻辑,也许将它组合成一行?

谢谢!

后续问题:

目前的解决方案是,

t_new = [365*year+day for year in range(10) for day in range(180) if day%30 < 10]

根据每个索引的值编辑原始数组。我想在第二个数组中只保留完全相同的索引,其值实际上是随机的,有没有办法将上述内容转换为索引操作?

【问题讨论】:

  • 闰年呢?
  • 是的,我暂时忽略这些 :) 一年中只有简单的 365 天
  • 您列表中的拼写错误:for i, in ...
  • @MosesKoledoye 谢谢,现已修复
  • 你拥有的是lists,而不是arrays。后者也存在,它们不是列表。

标签: python arrays list list-comprehension


【解决方案1】:

注意:请注意,您在此处过度简化了日历。 闰年在这里被忽略了。

你可以这样做:

[day for year in range(10) for day in range(365*year,365*year+180)]

代码工作如下:首先我们遍历years:范围从0(包含)到10(排除),所以0、1、2、3、4、5、6、7、8 , 和 9.

接下来,我们每年都使用day365*year(“虚拟年”开始的那一天)到365*year+180(我们的180 天结束的那一天)进行迭代。

对于每一天,我们都会将其添加到列表中。

这也比在列表推导中使用if 过滤语句更有效:这里只生成“有效”天。过滤器当然可以获得相同的功能,但您将首先生成一组(可能很大)您必须稍后撤回的值。

现在我想做的是保留每 30 个剩余数据中的前 10 个。

我们可以通过在此处添加一个额外的过滤器来做到这一点:

[365*year+day for year in range(10) for day in range(180) if day%30 < 10]

这将生成:

>>> [365*year+day for year in range(2) for day in range(180) if day%30 < 10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524]

(我只生成了前两年的列表)

编辑:如果您想要上述索引的数组索引,那么您可以简单地使用:

[a[365*year+day] for year in range(10) for day in range(180) if day%30 < 10]

a 是您的原始值列表。

【讨论】:

  • 非常感谢!这很棒,它可以让我随意使用其他类型的观察计划:) 是的,我现在忽略了闰年,不想在我能走路之前跑步!
  • 后续问题,是否可以根据数组的索引来编写它,这样我也可以从第二个数组中删除相同的元素,而不管它们的值如何?
  • @RichardHall:你能具体说明你在索引方面的意思吗?也许用一个例子来更新你的问题。
  • 我添加了第二个问题
  • @RichardHall:这能回答你的问题吗?
【解决方案2】:

能够生成一个列表,其中包含在较长时间段内重复的连续值集 比如[1,2,3,11,12,13,21,22,23,...],我们需要提供4个参数

  • 连续部分start_no的起始编号
  • 连续元素的数量 elem_count
  • 周期(数)周期
  • 您考虑的总天数

示例代码

start_no = 1
elem_count = 3
period = 10
tot = 3650
t_new = [x for x in range (tot) if x%period<=elem_count and x%period>=start_no]
print(t_new)

【讨论】:

    【解决方案3】:

    另一种方法是使用生成器来节省一些内存,并且可能更符合 Python 风格...

    """ This approach (using a function with yield statement) is called a generator
    It allows to create series of data without reserving memory for the entire thing
    only the current few parameters are stored in memory"""
    
    def iterfunc(start_no, elem_count, period):
        """this is the generator"""
        i = start_no
        while 1:
            if i%period<=elem_count and i%period>=start_no :
                yield i
            i+=1
    
    """ Need to create an instance of the generator,
    so that this instance remembers our parameters,
    also this way we can create more instances with 
    different parameters in each one
    """
    day = iterfunc(1, 3, 10)
    
    """ Here we print the days, but equally well we can append each to a list """
    for x in range(30):
        print(day.next())
    

    【讨论】:

    • 我会在同一个答案中添加多个答案,而不是单独添加。
    猜你喜欢
    • 1970-01-01
    • 2021-09-28
    • 2021-10-19
    • 2021-10-03
    • 1970-01-01
    • 2014-09-21
    • 2010-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多