我有一个以下数据框。(数据框中的实际列超过30个)
ID col1 col2 col3 col4
1 a## b## HO HO
2 c## d23 c## HO
3 a## k## z## s#
4 c## b12 a12 c12
5 b## HO z## HO
我想创建一个新的数据框来过滤具有以下内容的行 所有以'##'结尾的字符串,并且如果该行中的一个单元格包含'HO',我想跳过它,如果其余各列包含以##
结尾的字符串,则返回一行在上述情况下,新数据框将如下所示:
ID col1 col2 col3 col4
1 a## b## HO HO
3 a## k## z## s#
5 b## HO z## HO
我正在做
m = np.logical_and.reduce([
[x.endswith('##') for x in df[c] ] for c in df.columns if x!='HO'] )
但是df [m]仅给出了下一行,而没有给出另外两行
3 a## k## z##
我该如何解决?
答案 0 :(得分:1)
您可以如下组合布尔过滤器。请注意,只有两种有效的方案:要么有2个以'##'
结尾的字符串,一个等于'HO'
,要么有所有3个以'##'
结尾的字符串。
suffix = df.iloc[:, 1:].apply(lambda s: s.str[-2:].eq('##')).sum(1)
value = df.iloc[:, 1:].eq('HO').sum(1)
res = df[(suffix.eq(2) & value.eq(1)) | suffix.eq(3)]
print(res)
ID col1 col2 col3
0 1 a## b## HO
2 3 a## k## z##
4 5 b## HO z##
答案 1 :(得分:1)
您可以将“ HO”替换为虚拟字符串“ ##”,将结果存储为临时DataFrame,计算临时模板的掩码,然后将其索引回df
。
# df = df.set_index('ID') # Run this if not already done.
df
col1 col2 col3
ID
1 a## b## HO
2 c## d23 c##
3 a## k## z##
4 c## b12 a12
5 b## HO z##
u = df.replace('HO', '##')
m = np.logical_and.reduce([
[x.endswith('##') for x in u[c]] for c in u.columns]
)
df[m]
col1 col2 col3
ID
1 a## b## HO
3 a## k## z##
5 b## HO z##
答案 2 :(得分:0)
您可以尝试以下方法:
import pandas as pd
import numpy as np
data = {'col1':['a##', 'c##', 'a##', 'c##', 'b##'], 'col2':['b##', 'd23', 'k##', 'b12', 'HO'], 'col3': ['HO', 'c##', 'z##', 'a12', 'z##']}
df = pd.DataFrame(data = data)
m = np.logical_and.reduce([[('##' in x) | (x=='HO') for x in df[c] ]for c in df.columns ])
print(df, '\n\n',df[m])
col1 col2 col3
0 a## b## HO
1 c## d23 c##
2 a## k## z##
3 c## b12 a12
4 b## HO z##
col1 col2 col3
0 a## b## HO
2 a## k## z##
4 b## HO z##