在没有forloop的情况下,基于另外两个序列填充一个序列

2024-04-27 00:05:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个系列:s1和s2,充满了一年中每小时的数据。我想创建另一个系列,s3以便:

  • 如果在特定小时内,s1>;0和s1>;s2,s3=s1
  • 如果s1>;0且s1<;=s2,则s3=s2
  • 如果s1<;0,s3=0

所以我可以做一些像

for i in range(1,len(s1)):
    if (s1.iat[i] > 0 and s1.iat[i]>s2.iat[i]):
        s3.iat[i] = s1.iat[i]
    elif (s1.iat[i] > 0 and s1.iat[i]>s2.iat[i]):
        s3.iat[i] = s2.iat[i]
    else:
        s3.iat[i] = 0

但我相信有一个更优雅,希望更快,这样做的方法。我尝试过许多布尔索引和努比。哪里,但我不知道如何告诉Python执行“a[b>;c]=b”。它似乎不喜欢按行比较不同的数组。你知道吗


Tags: and数据inltgtforlenif
3条回答

您应该能够执行以下操作(假设您的数组是numpy数组):

idx = (s1 > 0) & (s1 > s2)
s3[idx] = s1[idx]

idy = (s1 > 0) & (s1 <= s2)
s3[idy] = s2[idy]

idz = (s1 < 0)
s3[idz] = 0

例如:

import numpy as np
s1 = np.array([1,2,3,4,-1])
s2 = np.array([2,1,3,4,-2])

# initialize s3
s3 = np.ones(len(s1))

# do some numpy indexing magic 
idx = (s1 > 0) & (s1 > s2)
s3[idx] = s1[idx]

idy = (s1 > 0) & (s1 <= s2)
s3[idy] = s2[idy]

idz = (s1 < 0)
s3[idz] = 0

print s3
# [ 2.  2.  3.  4.  0.]
for i in enumerate(s1):
    c1 = int(s1[i] < 0)
    c2 = int(s1[i]>s2[i])

    s3[i] =  c1*0 + int(not c1)*( s1[i]*c2 + s2[i]*(not c2) )
map(lambda a: 0 if a[0]<0 else a[0] if a[0]>a[1] else a[1],  zip(s1,s2))

这里有一些工作..

>>> s1=[-1,2,3,4,1,2,3,4]
>>> s2=[0,1,2,3,4,5,6,7]
>>> map(lambda a: 0 if a[0]<0 else a[0] if a[0]>a[1] else a[1], zip(s1,s2))
[0, 2, 3, 4, 4, 5, 6, 7]

这可能有助于解释……

>>> zip(s1,s2)
[(-1, 0), (2, 1), (3, 2), (4, 3), (1, 4), (2, 5), (3, 6), (4, 7)]

如果你把上面的应用到你的代码中。。。我不确定我是否会正确地在我的结束,因为我不知道什么是iat。你知道吗

如果数组真的很大,我会用itertools.izip替换zip,因为那样会返回一个迭代器。你知道吗

相关问题 更多 >