我有以下数据框

id  pattern1    pattern2    pattern3
 1  a-b-c       a-b--       a-b-c
 2  a-a--       a-b--       a-c--
 3  a-v--       a-m--       a-k--
 4  a-b--       a-n--       a-n-c


我想过滤包含模式的行-在所有列的末尾。
在这种情况下,输出将是

 2  a-a--       a-b--       a-c--
 3  a-v--       a-m--       a-k--


到目前为止,我只能考虑做以下事情

df[(len(df['pattern1'].str.split('--')[1])==0) & \
   (len(df['pattern2'].str.split('--')[1])==0) & \
   (len(df['pattern3'].str.split('--')[1])==0)]


这是行不通的。另外,我不能写所有列的名称,因为这是20列。
在该行中所有列均符合特定模式/条件的情况下,如何过滤行?

最佳答案

首先将“ id”设置为索引(如果尚未完成)。

df = df.set_index('id')


检查每个字符串的一种方法是使用applymap调用str.endswith

df[df.applymap(lambda x: x.endswith('--')).all(1)]

   pattern1 pattern2 pattern3
id
2     a-a--    a-b--    a-c--
3     a-v--    a-m--    a-k--




另一个选项是apply为每一列调用pd.Series.str.endswith

df[df.apply(lambda x: x.str.endswith('--')).all(1)]

   pattern1 pattern2 pattern3
id
2     a-a--    a-b--    a-c--
3     a-v--    a-m--    a-k--




最后,为了提高性能,您可以使用logical_and.reduce对列表理解内的AND掩码:

# m = np.logical_and.reduce([df[c].str.endswith('--') for c in df.columns])
m = np.logical_and.reduce([
    [x.endswith('--') for x in df[c]] for c in df.columns])
m
# array([False,  True,  True, False])

df[m]
   pattern1 pattern2 pattern3
id
2     a-a--    a-b--    a-c--
3     a-v--    a-m--    a-k--




如果还有其他列,但是您只想考虑那些名为“ pattern *”的列,则可以在DataFrame上使用filter

u = df.filter(like='pattern')


现在使用u重复上述选项,例如,第一个选项将是

df[u.applymap(lambda x: x.endswith('--')).all(1)]


...等等。

10-05 19:19