使用python的2个不同数组拖动值(simil触发器)

使用python的2个不同数组拖动值(simil触发器),python,numpy,pandas,Python,Numpy,Pandas,我想从2个不同的数组中获得一个新数组(命名结果),其中: 0 _ 0 => Hold state 1 _ 0 => 1 0 _ 1 => 0 1 _ 1 => 0 例如: array1 array2 Result 0 0 0 0 1 0 1 1 0 1 0 1 0 0 1 0

我想从2个不同的数组中获得一个新数组(命名结果),其中:

0 _ 0 => Hold state
1 _ 0 => 1
0 _ 1 => 0
1 _ 1 => 0
例如:

array1  array2  Result
     0       0       0
     0       1       0
     1       1       0
     1       0       1
     0       0       1
     0       0       1
     1       0       1
     0       0       1
     1       1       0
     0       0       0
     0       1       0
     0       0       0
     1       0       1
     0       0       1
就像 唯一的区别是
11=>0

我想用熊猫或裸体。谢谢你的帮助。我写了这篇文章,但它太慢了

def FLIP(array1, array2):

    assert array1.index.equals(array2.index), 'Indices do not match'
    array = pd.Series(False, dtype=bool, index=array1.index)
    i = 0
    while i < len(array1):
        if array1[i]:
            array[i] = True
            for j in xrange(i, len(array2)):
                if array2[j]:
                    array[j] = False
                    break
                array[j] = True
            i = j
        i += 1
    return array.fillna(value=False)
def翻转(阵列1、阵列2):
断言array1.index.equals(array2.index),“索引不匹配”
array=pd.Series(False,dtype=bool,index=array1.index)
i=0
而我
您要查找的结果取决于历史,因此我不知道有多少方法可以避免在两个数组上循环

def flip(array1, array2):

    currentstate = 0
    result = []

    for i, j in zip(array1, array2):

        if (i < j):

            currentstate = 0

        if (j < i):

            currentstate = 1

        result.append(currentstate)

    return np.array(result)
def翻转(阵列1、阵列2):
当前状态=0
结果=[]
对于拉链中的i,j(阵列1,阵列2):
如果(i
您可以使用前向填充函数来避免python在数据上循环

除了“保持状态”部分,其余部分基本上是按位移位

例如:

import pandas as pd

array1 = [0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0]
array2 = [0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0]

expected = [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1]

def flip(series1, series2):
    series1, series2 = pd.Series(series1), pd.Series(series2)

    out = pd.Series(np.nan, series1.index)
    out[:] = (series1 >> series2).astype(int)
    out[(series1 == 0) & (series2 == 0)] = np.nan
    return out.ffill()

print flip(array1, array2).values
print expected

请注意,这将保留未定义的起始值。如果您愿意,您可以使用任何有意义的值(例如0)来填充它。

如果我理解正确,我们可以利用熊猫如何对待
nan
来处理“保持”逻辑:

这将在测试用例中提供预期结果:

>>> df
    array1  array2  Result  result_computed
0        0       0       0                0
1        0       1       0                0
2        1       1       0                0
3        1       0       1                1
4        0       0       1                1
5        0       0       1                1
6        1       0       1                1
7        0       0       1                1
8        0       1       0                0
9        0       0       0                0
10       0       1       0                0
11       0       0       0                0
12       1       0       1                1
13       0       0       1                1
总的来说,似乎与您的输出相匹配:

from itertools import product

def check():
    for w in range(1, 9):
        for a0 in product(range(2), repeat=w):
            for a1 in product(range(2), repeat=w):
                s0, s1 = pd.Series(a0), pd.Series(a1)
                flipper_result = flipper(s0, s1)
                FLIP_result = FLIP(s0, s1)
                assert (flipper_result == FLIP_result).all()
    return True

>>> check()
True
使用。这似乎比提供的方法快得多。在10000个元素的数组中,速度大约快50倍。在10^6阵列上,需要220毫秒

In [80]: data = pd.DataFrame({
   ....:     'array1': [0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0],
   ....:     'array2': [0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
   ....: })

In [81]: flipflop = pd.DataFrame({
   ....:     'array1': [0, 1, 0, 1],
   ....:     'array2': [0, 0, 1, 1],
   ....:     'Result': [pd.np.nan, 1, 0, 0]
   ....: })

In [82]: data.merge(flipflop, how='left', on=['array1', 'array2']).ffill().fillna(0)
Out[82]:
    array1  array2  Result
0        0       0       0
1        0       1       0
2        1       1       0
3        1       0       1
4        0       0       1
5        0       0       1
6        1       0       1
7        0       0       1
8        0       1       0
9        0       0       0
10       0       1       0
11       0       0       0
12       1       0       1
13       0       0       1

In [83]: data = pd.DataFrame({
   ....:     'array1': pd.np.random.random_integers(0, 1, 10000),
   ....:     'array2': pd.np.random.random_integers(0, 1, 10000),
   ....: })

In [84]: %timeit FLIP(data.array1, data.array2)
10 loops, best of 3: 168 ms per loop

In [85]: %timeit data.merge(flipflop, how='left', on=['array1', 'array2']).ffill().fillna(0)
100 loops, best of 3: 2.97 ms per loop

抱歉,我不明白这一点,您必须解释如何获得结果的过程。这就像闩锁SR触发器设备。唯一的区别是1 1=>0我想使用pandas或numpy。我想获得一个新数组(命名为Result)来自两个不同的数组,其中:-0 0=>Hold state-1 0=>1-0 1=>0-1 1=>0我更改了代码,缺少了一行。我不会使用,因为我有一个10^6行的数据帧,它太慢了。@ARpython-值得一提的是,DSM的答案比我的更有效。不过,它们都是相同的基本想法。@Joe:它们不仅是相同的基本想法,当我一分钟前看到你做了同样的事情时,我几乎没有击中帖子(菲尔):-)@DSM-当我看到你的时,我几乎删除了我的:)难以置信。这个社区太棒了。再次感谢大家
In [80]: data = pd.DataFrame({
   ....:     'array1': [0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0],
   ....:     'array2': [0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
   ....: })

In [81]: flipflop = pd.DataFrame({
   ....:     'array1': [0, 1, 0, 1],
   ....:     'array2': [0, 0, 1, 1],
   ....:     'Result': [pd.np.nan, 1, 0, 0]
   ....: })

In [82]: data.merge(flipflop, how='left', on=['array1', 'array2']).ffill().fillna(0)
Out[82]:
    array1  array2  Result
0        0       0       0
1        0       1       0
2        1       1       0
3        1       0       1
4        0       0       1
5        0       0       1
6        1       0       1
7        0       0       1
8        0       1       0
9        0       0       0
10       0       1       0
11       0       0       0
12       1       0       1
13       0       0       1

In [83]: data = pd.DataFrame({
   ....:     'array1': pd.np.random.random_integers(0, 1, 10000),
   ....:     'array2': pd.np.random.random_integers(0, 1, 10000),
   ....: })

In [84]: %timeit FLIP(data.array1, data.array2)
10 loops, best of 3: 168 ms per loop

In [85]: %timeit data.merge(flipflop, how='left', on=['array1', 'array2']).ffill().fillna(0)
100 loops, best of 3: 2.97 ms per loop