Создание столбца на основе значений в отдельной строке

Вот пример моего фрейма данных:

df = pd.DataFrame([['Arsenal FC', '', ''],
                   ['In', 'Age', 'Nat.'],
                   ['Leandro Trossard', 28, 'Belgium'],
                   ['Jakub Kiwior', 22, 'Poland'],
                   ['Jorginho', 32, 'Italy'],
                   ['Chelsea FC', '', ''],
                   ['In', 'Age', 'Nat.'],
                   ['Enzo Fernández ', 22, 'Argentina'],
                   ['Mykhaylo Mudryk', 22, 'Ukraine'],
                  ], columns=['Player', 'Age', 'Nat.'])

Я хочу создать новый столбец "Club", который принимает строковое значение ячейки в "Player" и прикрепляет его к игроку ниже.

Сложность заключается в том, чтобы правильно clubs назначить правильно players

Это мой желаемый результат:

df = pd.DataFrame([['In', 'Age', 'Nat.'],
                   ['Leandro Trossard', 28, 'Belgium', 'Arsenal FC'],
                   ['Jakub Kiwior', 22, 'Poland', 'Arsenal FC'],
                   ['Jorginho', 32, 'Italy', 'Arsenal FC'],
                   ['In', 'Age', 'Nat.'],
                   ['Enzo Fernández ', 22, 'Argentina', 'Chelsea FC'],
                   ['Mykhaylo Mudryk', 22, 'Ukraine', 'Chelsea FC'],
                  ], columns=['Player', 'Age', 'Nat.', 'Club'])

Я не могу найти другой вопрос, который относится к этой проблеме. Возможно ли это в питоне?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
66
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Один из вариантов использования логических масок с mask и ffill:

# which rows are empty string on Age?
m1 = df['Age'].ne('')
# which row are not internal headers?
m2 = df['Player'].ne('Player')

out = df[m1&m2].assign(Club=df.loc[m2, 'Player'].mask(m1).ffill())

Выход:

             Player Age       Nat.        Club
2  Leandro Trossard  28    Belgium  Arsenal FC
3      Jakub Kiwior  22     Poland  Arsenal FC
4          Jorginho  32      Italy  Arsenal FC
7   Enzo Fernández   22  Argentina  Chelsea FC
8   Mykhaylo Mudryk  22    Ukraine  Chelsea FC

Промежуточные продукты:

             Player     m1        mask       ffill
0        Arsenal FC  False  Arsenal FC  Arsenal FC
2  Leandro Trossard   True         NaN  Arsenal FC
3      Jakub Kiwior   True         NaN  Arsenal FC
4          Jorginho   True         NaN  Arsenal FC
5        Chelsea FC  False  Chelsea FC  Chelsea FC
7   Enzo Fernández    True         NaN  Chelsea FC
8   Mykhaylo Mudryk   True         NaN  Chelsea FC

сохранение строк In/Age/Nat

# which rows are empty string on Age?
m1 = df['Age'].ne('')
# which row are not internal headers?
m2 = df['Player'].ne('In')

out = df[m1].assign(Club=df.loc[m2, 'Player'].mask(m1).ffill())

Выход:

             Player  Age       Nat.        Club
1                In  Age       Nat.         NaN
2  Leandro Trossard   28    Belgium  Arsenal FC
3      Jakub Kiwior   22     Poland  Arsenal FC
4          Jorginho   32      Italy  Arsenal FC
6                In  Age       Nat.         NaN
7   Enzo Fernández    22  Argentina  Chelsea FC
8   Mykhaylo Mudryk   22    Ukraine  Chelsea FC

Привет @mozway! Это не работает для меня прямо сейчас, но я отредактировал вопрос, чтобы отразить мой фактический фрейм данных.

code_machine 08.02.2023 18:05

@code_machine вы, наверное, сами догадались, что теперь вам нужно использовать m2 = df['Player'].ne('In'), аналогично, если у вас есть NaN вместо пустых строк, вы можете заменить ne('') на notna() ;)

mozway 08.02.2023 18:06

Спасибо! Есть ли способ использовать этот метод, не удаляя столбцы ['In', 'Age', 'Nat.']?

code_machine 08.02.2023 18:12

Привет @mozway, возможно ли добиться того, о чем я упоминал в комментарии выше? Метод 6c00h работает хорошо, но требует создания списка из 60+ названий клубов.

code_machine 09.02.2023 10:07

@code_machine да конечно, нужно просто удалить &m2, смотрите обновление

mozway 09.02.2023 10:24

Отредактировано:

df = pd.DataFrame([['Arsenal FC', '', ''],
                   ['In', 'Age', 'Nat.'],
                   ['Leandro Trossard', 28, 'Belgium'],
                   ['Jakub Kiwior', 22, 'Poland'],
                   ['Jorginho', 32, 'Italy'],
                   ['Chelsea FC', '', ''],
                   ['In', 'Age', 'Nat.'],
                   ['Enzo Fernández ', 22, 'Argentina'],
                   ['Mykhaylo Mudryk', 22, 'Ukraine'],
                  ], columns=['Player', 'Age', 'Nat.'])

clubs = []
current_club = None
for i, row in df.iterrows():
    if row['Player'] in ['Arsenal FC', 'Chelsea FC']:
        current_club = row['Player']
    elif row['Player'] == 'In':
        continue
    else:
        clubs.append(current_club)

df['Club'] = clubs

print(df)

Выход:

           Player Age     Nat.       Club
0      Arsenal FC        Arsenal FC
1             In   Age     Nat.      NaN
2  Leandro Trossard  28   Belgium  Arsenal FC
3     Jakub Kiwior  22   Poland  Arsenal FC
4         Jorginho  32    Italy  Arsenal FC
5       Chelsea FC        Chelsea FC
6             In   Age     Nat.      NaN
7  Enzo Fernández   22 Argentina  Chelsea FC
8  Mykhaylo Mudryk  22   Ukraine  Chelsea FC

Редактировать 2: Несколько названий клубов

clubs = ['Arsenal FC', 'Chelsea FC', 'Other Club 1', 'Other Club 2', ..., 'Other Club n']

def get_club(row, clubs):
    if row['Player'] in clubs:
        return row['Player']
    else:
        return ''

df['Club'] = ''
club = ''
for index, row in df.iterrows():
    if row['Player'] in clubs:
        club = row['Player']
    else:
        df.at[index, 'Club'] = club

df = df[df['Club'] != ''].reset_index(drop=True)
df['Club'] = df.apply(lambda x: get_club(x, clubs), axis=1)

Всем привет! Можно ли использовать этот метод, не удаляя столбцы ['In', 'Age', 'Nat.']?

code_machine 08.02.2023 18:28

Большое спасибо. Есть ли другой способ реализовать этот код, когда существует несколько названий клубов (60+), кроме «Арсенал» и «Челси»?

code_machine 08.02.2023 18:40

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

6c00h 08.02.2023 19:02

Другие вопросы по теме