我有一个包含许多列的数据框,其中任意数目的列名称适合特定的字符串模式。我想创建一个新列,如果其他任何列中有一个“ r”,则将其设置为“ r”。我可以做这样的事情:

for col in df.columns:
    if 'abc' in col:
        for i in df.index:
            if df.ix[i, col] == 'r':
                df.ix[i, 'newcol'] = 'r'


但是,这有点丑陋且缓慢。有更快的方法吗?

编辑:包括我的源数据可能看起来像的示例:

df = pd.DataFrame({'abc1':['r','r','n','n'], 'abc2':['r','n','n','r'], 'xyz1':['r','n','n','n'], 'xyz2':['n','n','r','n']})


我需要的输出(在'newcol'中)是:

  abc1 abc2 xyz1 xyz2 newcol
0    r    r    r    n      r
1    r    n    n    n      r
2    n    n    n    r    nan
3    n    r    n    n      r


(只要不是'r',nan几乎可以用任何东西代替)。
另外,newcol可以包含True, True, False, True,对于我的目的也可以正常工作。

最佳答案

好吧,我可能会这样做(一个示例数据框有望很好地捕获您的情况):

>>> df

   A  B abc1 abc2 abc3 abc4
0  1  4    x    r    a    d
1  1  3    y    d    b    e
2  2  4    z    e    c    r
3  3  5    r    g    d    f
4  4  8    z    z    z    z


获取感兴趣的列:

>>> cols = [x for x in df.columns if 'abc' in x]
>>> cols
['abc1', 'abc2', 'abc3', 'abc4']

>>> df['newcol'] = (df[cols] == 'r').any(axis=1).map({True:'r',False:'np.nan'})
>>> df

  A  B abc1 abc2 abc3 abc4  newcol
0  1  4    x    r    a    d       r
1  1  3    y    d    b    e  np.nan
2  2  4    z    e    c    r       r
3  3  5    r    g    d    f       r
4  4  8    z    z    z    z  np.nan


这应该很快。我认为即使在这里使用map也会被Cythonized调用。如果一个布尔向量足以用于newcol,则可以将其简化为以下形式:

>>> df['newcol'] = (df[cols] == 'r').any(axis=1)
>>> df

   A  B abc1 abc2 abc3 abc4 newcol
0  1  4    x    r    a    d   True
1  1  3    y    d    b    e  False
2  2  4    z    e    c    r   True
3  3  5    r    g    d    f   True
4  4  8    z    z    z    z  False


现在,如果需要检查字符串是否包含“ r”而不是等于“ r”,则可以执行以下操作:

>>> df

  A  B abc1  abc2 abc3 abc4
0  1  4    x  root    a    d
1  1  3    y     d    b    e
2  2  4    z     e    c  bar
3  3  5    r     g    d    f
4  4  8    z     z    z    z

>>> cols = [x for x in df.columns if 'abc' in x]
>>> df['newcol'] = df[cols].apply(lambda x: x.str.contains('r'),axis=0).any(axis=1)
>>> df['newcol'] = df['newcol'].map({True:'r',False:'np.nan'})
>>> df

   A  B abc1  abc2 abc3 abc4  newcol
0  1  4    x  root    a    d       r
1  1  3    y     d    b    e  np.nan
2  2  4    z     e    c  bar       r
3  3  5    r     g    d    f       r
4  4  8    z     z    z    z  np.nan


这应该仍然非常快,因为它对每个列使用pandas向量化的字符串方法(应用是跨列的,而不是行的迭代)。

08-24 13:46