两列之间的Pandas以开头匹配操作

4

我的pandas数据帧有两列,我需要检查列A每一行的值是否是以列B对应行的值开头的字符串,反之亦然。

似乎Series方法.str.startswith无法处理矢量化输入,所以我需要在列表推导式中对两列进行zip处理,并创建一个与任何两列中的一列具有相同索引的新的pd.Series

我希望这是一个矢量化操作,可用于操作可迭代对象的.str访问器,但类似于这样的操作会返回NaN:

df = pd.DataFrame(data={'a':['x','yy'], 'b':['xyz','uvw']})
df['a'].str.startswith(df['b'])

我的工作解决方案如下:

pd.Series(index=df.index, data=[a.startswith(b) or b.startswith(a) for a,b in zip(df['a'],df['b'])])

我怀疑有更好的方法来解决这个问题,因为这样做也会使系列上的所有字符串方法受益。

是否有更美观或更有效的方法来做到这一点?

1个回答

2

一个想法是使用np.vectorize,但由于处理字符串的性能只比您的解决方案好一点:

def fun (a,b):
    return a.startswith(b) or b.startswith(a)

f = np.vectorize(fun)
a = pd.Series(f(df['a'],df['b']), index=df.index)
print (a)
0     True
1    False
dtype: bool

df = pd.DataFrame(data={'a':['x','yy'], 'b':['xyz','uvw']})
df = pd.concat([df] * 10000, ignore_index=True)

In [132]: %timeit pd.Series(index=df.index, data=[a.startswith(b) or b.startswith(a) for a,b in df[['a', 'b']].to_numpy()])
42.3 ms ± 516 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [133]: %timeit pd.Series(f(df['a'],df['b']), index=df.index)
9.81 ms ± 119 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [134]: %timeit pd.Series(index=df.index, data=[a.startswith(b) or b.startswith(a) for a,b in zip(df['a'],df['b'])])
14.1 ms ± 262 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

#sammywemmy solution
In [135]: %timeit pd.Series([any((a.startswith(b), b.startswith(a))) for a, b in df.to_numpy()], index=df.index)
46.3 ms ± 683 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接