Создайте новый столбец Pandas df с логическими значениями, которые зависят от другого столбца - PullRequest
0 голосов
/ 27 октября 2018

Мне нужно добавить новый столбец в фрейм данных Pandas.

Если в столбце «Индуцирование» содержится текст (не пустой и не «»), мне нужно добавить 1, иначе 0

Я пробовал с

df['newColumn'] = np.where(df['INDUCING']!="", 1, 0)

Эта команда работает только для значений, которые являются строками, инициализированными как "", но не работает, если она пуста.

Есть идеи, как правильно добавить этот столбец?

Ответы [ 3 ]

0 голосов
/ 27 октября 2018

По законам Де Моргана , NOT (cond1 ИЛИ cond2) эквивалентно И (НЕ (cond1) И НЕ (cond2)).

Вы можете комбинировать условия с помощью побитовых операторов "и" (&) / "или" (|) в зависимости от ситуации. Это дает логическую серию, которую вы затем можете разыграть до int:

df['newColumn'] = (df['INDUCING'].ne('') & df['INDUCING'].notnull()).astype(int)
0 голосов
/ 27 октября 2018

Поскольку встроенный bool создает True для строки точно, если она не пустая, вы можете достичь этого просто с помощью

df['newColumn'] = df['INDUCING'].astype(bool).astype(int)

Некоторые сравнения производительности:

In [61]: df = pd.DataFrame({'INDUCING': ['test', None, '', 'more test']*10000})

In [63]: %timeit np.where(df['INDUCING'].fillna('') != "", 1, 0)
5.68 ms ± 500 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [62]: %timeit (df['INDUCING'].ne('') & df['INDUCING'].notnull()).astype(int)
5.1 ms ± 223 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [64]: %timeit np.where(df['INDUCING'], 1, 0)
667 µs ± 25.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [65]: %timeit df['INDUCING'].astype(bool).astype(int)
655 µs ± 5.55 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [99]: %timeit df['INDUCING'].values.astype(bool).astype(int)
553 µs ± 18.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
0 голосов
/ 27 октября 2018

Проще всего было бы сначала .fillna('').Исправление:

df['newColumn'] = np.where(df['INDUCING'].fillna('') != "", 1, 0)

или передайте .astype (int) непосредственно в маску.Это преобразует True в 1 и False в 0:

df['newcol'] = (df['INDUCING'].fillna('') != '').astype(int)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...