[英]Drag value using 2 different array with python (simil flip flop)
我想从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设备唯一的区别是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)
您可以使用pandas forward fill函数来避免对数据进行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)。
如果我理解正确,我们可以利用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
使用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
你正在寻找的结果是依赖于历史的,所以我不知道避免两个数组上的循环的余地。
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.