为数字字符串创建一个指标,忽略 python pandas 中的特定数字
Creating an indicator for strings of numbers, ignoring a particular one in python pandas
我不知道如何给这个问题起标题,欢迎编辑。
我有一个pandas系列的数字(可以做成一个列表,类型并不重要)。
数字从 1 到 13。
例如:
13,13,1,1,1,1,13,2,1,1
我想查找相同数字的字符串,但不计算 13
如果它在中间或开头。
我想要 return 一个新列表,当 nth
元素是 13
或与 (n-1)th
相同时作为指示符。例如,这将是:
0,0,0,1,1,1,1,0,0,1
直到我观察到一个非 13 值,计数器才开始计数,然后它将 13s 计为之前的非 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
我不知道如何给这个问题起标题,欢迎编辑。
我有一个pandas系列的数字(可以做成一个列表,类型并不重要)。
数字从 1 到 13。
例如:
13,13,1,1,1,1,13,2,1,1
我想查找相同数字的字符串,但不计算 13
如果它在中间或开头。
我想要 return 一个新列表,当 nth
元素是 13
或与 (n-1)th
相同时作为指示符。例如,这将是:
0,0,0,1,1,1,1,0,0,1
直到我观察到一个非 13 值,计数器才开始计数,然后它将 13s 计为之前的非 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