Python 检查多个列中是否存在字符串,并向多个列中的单独列提供输出

Python 检查多个列中是否存在字符串,并向多个列中的单独列提供输出,python,pandas,split,multiple-columns,Python,Pandas,Split,Multiple Columns,我的数据框架如下所示: col1 col2 col3 col4 0 a-I - - 12.4 1 - a-I - 2.6 2 a-I - a-I 23 3 - a-I a-I 4 4 - - a-I 5 5 a-I a-I - 6.245 6 - a a 7.23 7 a a - 8 我想要的是

我的数据框架如下所示:

    col1  col2  col3  col4
0   a-I    -     -    12.4
1   -      a-I   -    2.6
2   a-I    -     a-I  23
3   -      a-I   a-I  4
4   -      -     a-I  5
5   a-I    a-I   -    6.245
6   -      a     a    7.23
7   a      a     -    8
我想要的是检查每列中是否存在
I
,而不是使用
-
拆分字符串生成
res
列。有人知道怎么做吗

预期结果如下:

    col1  col2  col3  col4 res
0   a-I    -     -    12.4  I 
1   -      a-I   -    2.6   I
2   a-I    -     a-I  23    I
3   -      a-I   a-I  4     I
4   -      -     a-I  5     I
5   a-I    a-I   -    6.245 I
6   -      a     a    7.23  -
7   a      a     -    8     -
设置

如果在数据帧中除了
str
之外还有其他数据类型,则需要将所有提到的
df
替换为
df.astype(str)

使用
numpy.where
str.contains

使用列表理解: 列表理解通常比内置的
pandas
string方法更快:

df.assign(res=['I' if 'I' in row else '-' for row in df.values.sum(1)])

两者都产生:

 col1 col2 col3 res
0  a-I    -    -   I
1    -  a-I    -   I
2  a-I    -  a-I   I
3    -  a-I  a-I   I
4    -    -  a-I   I
5  a-I  a-I    -   I
6    -    a    a   -
7    a    a    -   -

计时

或:

如果熊猫数据框包含字符串以外的类型,请执行以下操作:

df['res']=df.astype(str).sum(1).str.contains('I').map({False:'-',True:'I'})
print(df)

对于该示例,您的
res
列是什么样子的?请提供所需的输出。更新了问题。@abhi1610好的,这将返回带有新列的数据帧,但保留df不变。要直接更改df,可以编写
df['res']=np.where(df.sum(1).str.contains('I'),'I','-')
。谢谢您的回答。但是,如果存在除
str
之外的其他类型,该怎么办?@abhi1610 Do
df.astype(str)
然后仅使用字符串索引数据帧columns@user3483203我认为我们可以使用
df.astype(str).values来代替
df.values.astype(str)
在列表理解中给了我
类型错误:无法使用灵活类型执行reduce
感谢您的回答,但@user3483203有更好的答案。
df = pd.concat([df]*5000)

%timeit ['I' if 'I' in row else '-' for row in df.values.sum(1)]
9.29 ms ± 310 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit np.where(df.sum(1).str.contains('I'), 'I', '-')
69.4 ms ± 2.17 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df.sum(1).str.contains('I').map({False:'-',True:'I'})
83 ms ± 12.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
df['res']=df.sum(1).str.contains('I').map({False:'-',True:'I'})
print(df)
df['res']=df.astype(str).sum(1).str.contains('I').map({False:'-',True:'I'})
print(df)