Проверьте наличие строки в нескольких столбцах и передайте вывод отдельным столбцам в пандах - PullRequest
0 голосов
/ 30 августа 2018

У меня есть датафрейм следующим образом:

    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     -

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

OR

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

Если фрейм данных pandas содержит типы, отличные от строк, выполните:

df['res']=df.astype(str).sum(1).str.contains('I').map({False:'-',True:'I'})
print(df)
0 голосов
/ 30 августа 2018

Настройка

Если у вас есть другие типы данных, кроме str в вашем DataFrame, вам необходимо заменить все упоминания df на df.astype(str).

Использование numpy.where и str.contains

df.assign(res=np.where(df.sum(1).str.contains('I'), 'I', '-'))

Использование понимания списка:

Понимание списков часто быстрее встроенных pandas строковых методов:

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 = 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)
...