Создание столбца на основе присутствия части строки в нескольких других столбцах - PullRequest
0 голосов
/ 07 января 2019

У меня есть фрейм данных с именем df, который выглядит примерно так (за исключением того, что число столбцов 'mat_deliv' увеличивается до mat_deliv_8, и есть несколько сотен клиентов - я упростил это здесь).

Client_ID  mat_deliv_1  mat_deliv_2  mat_deliv_3  mat_deliv_4
C1019876   xxx,yyy,zzz  aaa,bbb,xxx  ccc          ddd
C1018765   yyy,zzz      xxx          bbb          None
C1017654   yyy,xxx      aaa,bbb      ccc          ddd
C1016543   aaa,bbb      ccc          None         None
C1019876   yyy          None         None         None

Я хочу создать новый столбец с именем xxx_deliv с двумя значениями 0 и 1. Я хочу установить xxx_deliv равным 1, если любой из mat_deliv_1, mat_deliv_2, mat_deliv_3 или mat_deliv_4 содержит xxx и 0, если их нет.

Итак, я хочу добавить столбец, который на примере df будет выглядеть так:

Client_ID  mat_deliv_1  mat_deliv_2  mat_deliv_3  mat_deliv_4  xxx_deliv
C1019876   xxx,yyy,zzz  aaa,bbb,xxx  ccc          ddd          1
C1018765   yyy,zzz      xxx          bbb          None         1
C1017654   yyy,xxx      aaa,bbb      ccc          ddd          1
C1016543   aaa,bbb      ccc          None         None         0
C1019876   yyy          None         None         None         0

Я знаю, что следующий код выполняет нужную задачу:

df['xxx_deliv'] = 0
df.loc[(df.Mat_deliv_1.str.contains("xxx", na=False)) |
       (df.Mat_deliv_2.str.contains("xxx", na=False)) |
       (df.Mat_deliv_3.str.contains("xxx", na=False)) |
       (df.Mat_deliv_4.str.contains("xxx", na=False)),
       'xxx_deliv'] = 1

Но я хотел бы иметь возможность делать это, не просматривая каждый отдельный столбец - мне нужно иметь возможность поиска по нескольким столбцам одновременно.

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Вам необходимо проверить каждый столбец в отдельности. Вы можете сделать это через apply, проверив, что строка содержит целевой текст. Затем примените any к строке (указав axis=1). Преобразуйте логический результат в целое число через .astype(int), а затем используйте assign, чтобы добавить его в качестве нового столбца в фрейм данных.

Я использовал loc[:, target_cols], чтобы указать диапазон поиска как все строки в кадре данных и все выбранные target_cols.

target_cols = ['mat_deliv_1', 'mat_deliv_2', 'mat_deliv_3', 'mat_deliv_4']
df = (df
      .assign(xxx_deliv=df.loc[:, target_cols].apply(lambda col: col.str.contains('xxx'))
      .any(axis=1)
      .astype(int))
>>> df
  Client_ID  mat_deliv_1  mat_deliv_2 mat_deliv_3 mat_deliv_4  xxx_deliv
0  C1019876  xxx,yyy,zzz  aaa,bbb,xxx         ccc         ddd          1
1  C1018765      yyy,zzz          xxx         bbb        None          1
2  C1017654      yyy,xxx      aaa,bbb         ccc         ddd          1
3  C1016543      aaa,bbb          ccc        None        None          0
4  C1019876          yyy         None        None        None          0
0 голосов
/ 07 января 2019

Вы можете использовать применить :

def contains(xs, pat='xxx'):
    return int(any(pat in x for x in xs.values))


df['xxx_deliv'] = df[['mat_deliv_1', 'mat_deliv_2', 'mat_deliv_3', 'mat_deliv_4']].apply(contains, axis=1)
print(df)

выход

  Client_ID  mat_deliv_1    ...    mat_deliv_4 xxx_deliv
0  C1019876  xxx,yyy,zzz    ...            ddd         1
1  C1018765      yyy,zzz    ...           None         1
2  C1017654      yyy,xxx    ...            ddd         1
3  C1016543      aaa,bbb    ...           None         0
4  C1019876          yyy    ...           None         0

[5 rows x 6 columns]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...