выполнить итерацию во всех строках фрейма данных и выполнить startswith()

#python #pandas #dataframe

#python #панды #фрейм данных

Вопрос:

мой df выглядит так:

df

как вы можете видеть, пользователь начинается с ‘ff’, и это может быть столбец access или любой другой столбец, а не столбец user.

я хочу создать новый столбец в этом df с именем «userId», где всякий раз, когда во всех столбцах есть «ff», скопируйте это значение в мой новый столбец «userId»

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

 hist.loc[hist.User.str.startswith("ff",na=False),'UserId']=hist['User'].str[2:]
  

есть ли какой-либо другой метод, который я могу использовать для одновременного перебора всех строк?

Спасибо

Комментарии:

1. Вы имеете в виду, что если все столбцы начинаются с ‘ff’, скопируйте остальную часть строки из ПОЛЬЗОВАТЕЛЬСКОГО столбца и нет, если это не так.

Ответ №1:

Если вы согласны с выбором только первого случая:

 df['UserID'] = df.apply(lambda x: x[x.str.startswith('ff')][:1], axis=1)
  

Комментарии:

1. x[x.str.startswith('ff')][0] выдаст ошибку индекса, если ни один столбец не начинается с ‘ff’

2. пожалуйста, опубликуйте полный ответ

Ответ №2:

Решение NumPy Pandas приведено ниже.

В случае неоднозначности (несколько ff строк подряд) принимается крайнее левое значение. В случае отсутствия (отсутствие ff строки в строке) NaN используется значение.

Попробуйте это онлайн!

 import pandas as pd, numpy as np

df = pd.DataFrame({
    'user':    ['fftest',     'fwadmin',     'fshelpdesk3', 'no',   'ffone'],
    'access':  ['fwadmin',    'ffuser2',     'fwadmin',     'user', 'fftwo'],
    'station': ['fshelpdesk', 'fshelpdesk2', 'ffuser3',     'here', 'three'],
})

sv = df.values.astype(np.str)
ix = np.argwhere(np.char.startswith(sv, 'ff'))[::-1].T
df.loc[ix[0], 'UserID'] = pd.Series(sv[(ix[0], ix[1])]).str[2:].values

print(df)
  

Вывод:

           user   access      station UserID
0       fftest  fwadmin   fshelpdesk   test
1      fwadmin  ffuser2  fshelpdesk2  user2
2  fshelpdesk3  fwadmin      ffuser3  user3
3           no     user         here    NaN
4        ffone    fftwo        three    one
  

Ответ №3:

Привет, вот моя попытка решить проблему, надеюсь, это поможет.

 d = df[df.apply(lambda x: x.str.startswith('ff'))]
df['user_id'] = d['user'].fillna(d['access'].fillna(d['station']))
  

Результат

         user   access      station  user_id
0       fftest  fwadmin   fshelpdesk   fftest
1      fwadmin  ffuser2  fshelpdesk2  ffuser2
2  fshelpdesk3  fwadmin      ffuser3  ffuser3