我不知道如何命名这个问题,欢迎编辑。
我有一系列 pandas 数字(可以做成一个列表,类型实际上并不重要)。
数字从 1 到 13。
例如:
13,13,1,1,1,1,13,2,1,1
我想找到相同数字的字符串,但不计算 13
如果它位于中间或开头。
我想返回一个新列表,当 nth
时作为指示符元素是 13
或与 (n-1)th
相同。例如,这将是:
0,0,0,1,1,1,1,0,0,1
直到我观察到非 13 时,计数器才会开始,然后它将 13 秒作为前一个非 13 值进行计数。
它还需要尽可能快,所以如果可能的话,我想避免带有大量 if 条件的疯狂循环。
最佳答案
开头的 13 很烦人;我想不出一种有效的矢量化方法来摆脱它们。也就是说,无论是
def method1(s):
out = ((s == s.shift()) | (s == 13)).astype(int)
for i, x in s.iteritems():
if x == 13: out[i] = 0
else: break
return out
def method2(s):
s13na = s.replace(13, np.nan).ffill()
indic = (s13na == s13na.shift()).astype(int)
return indic
应该可以工作。第一个方法只是询问某个数字是否等于之前的数字或 13,然后修补开头。第二个用 nan
替换所有 13,进行前向填充(以便将 13 替换为最后一个非 13 数字或 nan),然后进行通常的移位检查。这给出了正确的答案:
>>> method1(s)
0 0
1 0
2 0
3 1
4 1
5 1
6 1
7 0
8 0
9 1
dtype: int32
>>> (method1(s) == method2(s)).all()
True
性能取决于数组的大小和 13 秒的比例..
>>> %timeit method1(s)
1000 loops, best of 3: 1.13 ms per loop
>>> %timeit method2(s)
1000 loops, best of 3: 704 µs per loop
>>> s2 = pd.concat([s]*100000).reset_index(drop=True)
>>> %timeit method1(s2)
10 loops, best of 3: 75.8 ms per loop
>>> %timeit method2(s2)
1 loops, best of 3: 203 ms per loop
关于python - 为数字字符串创建一个指示符,忽略 python pandas 中的特定数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28256533/