Python: найти строку в нескольких столбцах и вернуть ее в новый столбец - PullRequest
1 голос
/ 23 января 2020

Привет, у меня есть данные Excel с несколькими столбцами, и мне нужно оштрафовать указанное c слово и вернуть его в новый столбец, таблица будет выглядеть так:

ID   col0  col1  col2  col3  col4  col5
1    jack  a/h   t/m   w/n   y/h    56
2    sam   z/n   b/w   null  null   93
3    john  b/i   y/d   p/d   null   33

Я хочу найти 'b 'в столбцах col1, col2, col3 и col4 и создайте новый столбец с именем "b", в котором возвращается значение ячейки со значением

результат будет выглядеть следующим образом

ID   col0  col1  col2  col3  col4  col5  b
1    jack  a/h   t/m   w/n   y/h    56   -
2    sam   z/n   b/w   null  null   93   b/w
3    john  b/i   y/d   p/d   null   33   b/i

и мне нужен эффективный способ сделать это, я пытался использовать, где, как это

df1 = df[['col1', 'col2', 'col3', 'col4']]

df1['b']==[x for x in df1.values[0] if any(b for b in lst if b in str(x))]

Я получил это из этого ответа { ссылка }

все же это у меня не работает snice У меня есть нулевое значение и строки, где условие не работает

Ответы [ 3 ]

2 голосов
/ 23 января 2020

Я бы использовал DataFrame.stack с callable:

cols = ['col1', 'col2', 'col3', 'col4']
df['b']=(df[cols].stack()
                 .loc[lambda x: x.str.contains('b')]
                 .reset_index(level=1,drop=1)
                #.fillna('-') #for the expected output
        )

Выход

   ID  col0 col1 col2 col3 col4  col5    b
0   1  jack  a/h  t/m  w/n  y/h    56  NaN
1   2   sam  z/n  b/w  NaN  NaN    93  b/w
2   3  john  b/i  y/d  p/d  NaN    33  b/i
2 голосов
/ 23 января 2020

Вот способ использования stack и str.contains с df.where:

cols = ['col1', 'col2', 'col3', 'col4']
df['b'] = (df[cols].where(df[cols].stack().str.contains('b')
         .unstack(fill_value=False)).ffill(1).iloc[:,-1])

print(df)

   ID  col0 col1 col2 col3 col4  col5    b
0   1  jack  a/h  t/m  w/n  y/h    56  NaN
1   2   sam  z/n  b/w  NaN  NaN    93  b/w
2   3  john  b/i  y/d  p/d  NaN    33  b/i
0 голосов
/ 23 января 2020

Чтобы избежать выбора столбцов, я использовал melt :

M = (df.copy()
     .melt(id_vars='ID')
     .loc[lambda x:x['value'].astype('str').str.contains('b')]
     .drop('variable',axis=1))

pd.merge(df,M,how='left',on='ID').rename({'value':'b'},axis=1)

    D   col0    col1    col2    col3    col4    col5     b
0   1   jack    a/h     t/m     w/n     y/h      56     NaN
1   2   sam     z/n     b/w     NaN     NaN      93     b/w
2   3   john    b/i     y/d     p/d     NaN      33     b/i
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...