我想从2个不同的数组中获取一个新数组(名为Result),其中:
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
就像
Latch SR Flip Flop device唯一的区别是1 1 => 0
我想用熊猫或numpy。谢谢您的帮助。我写了这个并且它有效,但它太慢了。
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)
答案 0 :(得分:3)
您可以使用pandas forward fill函数来避免对数据进行python循环。
除了&#34;保持状态&#34;部分,其余部分基本上是按位移动。
例如:
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)。
答案 1 :(得分:3)
如果我理解正确,我们可以利用pandas
如何对待nan
来处理“保持”逻辑:
def flipper(a1, a2):
res = pd.Series(index=a1.index)
res.loc[a1 == 1] = 1
res.loc[a2 == 1] = 0
res = res.ffill().fillna(0)
return res
这给出了测试用例中的预期结果:
>>> 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
答案 2 :(得分:1)
使用DataFrame.merge。这似乎比提供的方法快得多。在10,000个元素的数组上,它的速度提高了约50倍。在10 ^ 6阵列上,花了220ms。
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
答案 3 :(得分: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)