![](/img/trans.png)
[英]Most efficient method for creating new binary Series based on conditional in Pandas when the old series has missing data?
[英]Conditional length of a binary data series in Pandas
具有带有以下列的DataFrame:
df['A'] = [1,1,1,0,1,1,1,1,0,1]
通过某个极限值控制“ 1”系列长度的最佳矢量化方法是什么? 假设限制为2,则结果列“ B”必须看起来像:
A B
0 1 1
1 1 1
2 1 0
3 0 0
4 1 1
5 1 1
6 1 0
7 1 0
8 0 0
9 1 1
一种完全矢量化的解决方案是使用shift
- groupby
- cumsum
- cumcount
组合1来指示连续cumcount
短于2的位置(或您喜欢的任何限制值)。 然后, &
这种新的布尔系列与原列:
df['B'] = ((df.groupby((df.A != df.A.shift()).cumsum()).cumcount() <= 1) & df.A)\
.astype(int) # cast the boolean Series back to integers
这将在DataFrame中产生新列:
A B
0 1 1
1 1 1
2 1 0
3 0 0
4 1 1
5 1 1
6 1 0
7 1 0
8 0 0
9 1 1
1参见《 熊猫食谱》 ; 关于分组的部分,“像Python的itertools.groupby一样进行分组”
另一种方法(检查前两个是否为1):
In [443]: df = pd.DataFrame({'A': [1,1,1,0,1,1,1,1,0,1]})
In [444]: limit = 2
In [445]: df['B'] = map(lambda x: df['A'][x] if x < limit else int(not all(y == 1 for y in df['A'][x - limit:x])), range(len(df)))
In [446]: df
Out[446]:
A B
0 1 1
1 1 1
2 1 0
3 0 0
4 1 1
5 1 1
6 1 0
7 1 0
8 0 0
9 1 1
如果您知道该系列中的值都为0
或1
,那么我想您可以使用涉及卷积的小技巧。 复制列(不必是Pandas对象,它可以只是普通的Numpy数组)
a = df['A'].as_matrix()
并将其与比所需cutoff
长度长一的1序列进行卷积,然后切掉最后一个cutoff
元素。 例如, cutoff
值为2,您会这样做
long_run_count = numpy.convolve(a, [1, 1, 1])[:-2]
在这种情况下,所得数组给出在该元素之前(包括该元素)的3个元素中出现的1
的数目。 如果该数字为3,则说明您正在运行的长度超过了2。因此,只需将这些元素设置为零即可。
a[long_run_count > 2] = 0
现在,您可以将结果数组分配给DataFrame
的新列。
df['B'] = a
要将其转换为更通用的方法:
def trim_runs(array, cutoff):
a = numpy.asarray(array)
a[numpy.convolve(a, numpy.ones(cutoff + 1))[:-cutoff] > cutoff] = 0
return a
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.