Векторизация операции сопоставления на уровне строк в фрейме данных Pandas

#python #pandas #dataframe

Вопрос:

У меня есть фрейм данных pandas с данными о баскетбольной игре в следующем формате (упрощенном):

      Shooter       h1         h2        h3           h4          h5  th1  th2  th3  th4  th5  
0  K. Irving  K. Love  K. Irving  L. James  T. Thompson  D. Liggins  0.5  1.4  5.3  4.8  4.3  
1    K. Love  K. Love  K. Irving  L. James  T. Thompson  D. Liggins  0.6  1.5  5.4  4.9  4.4  
2   L. James  K. Love  K. Irving  L. James  T. Thompson  D. Liggins  0.7  1.6  5.5  5.0  4.5  
 

где «th1″ соответствует количеству времени, которое игрок в » h1 » сыграл в игре до этой игры. Я надеюсь извлечь количество времени, которое каждый стрелок сыграл в игре во время своего выстрела, сопоставив стрелка с соответствующим столбцом «h», а затем извлекая соответствующее значение «th». В основном:

      Shooter  TimeInGame
0  K. Irving  1.4
1    K. Love  0.6
2   L. James  5.5
 

Я сделал это в зачаточном виде (df.iterrows()), но надеялся векторизовать эту операцию, чтобы быстро просмотреть большое количество данных. Есть ли способ сделать это?

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

1. Являются h ли столбцы всегда постоянными строками, например h1 , всегда K. Love ?

2. В настоящее время иногда встречаются np.nan, но их можно было бы отбросить

Ответ №1:

Попробуйте это:

 #Get all columns starting with 'h' and compare them with 'Shooter'
m = df[df.columns[df.columns.str.startswith('h')]].eq(df.Shooter,0)

#Get all columns starting with 'th' and extract the values where m is True
time_in_game = df[df.columns[df.columns.str.startswith('th')]]
              .values[range(len(df)), np.where(m)[1]]

pd.DataFrame({"Shooter": df["Shooter"], "TimeInGame": time_in_game})
 

Выход

      Shooter  TimeInGame
0  K. Irving         1.4
1    K. Love         0.6
2   L. James         5.5
 

Ответ №2:

Я не мог найти простого способа сделать это. Так что мой обходной путь таков:

 import pandas as pd
mask = df[["h1","h2","h3","h4","h5"]].eq(df["Shooter"],axis=0)
 

маска:

 h1      h2      h3      h4      h5
False   True    False   False   False
True    False   False   False   False
False   False   True    False   False
 

Затем найдите время каждого игрока:

 times = df[["th1","th2","th3","th4","th5"]].values[mask.values].flatten()
 

Наконец, создайте новый фрейм данных:

 df2 = pd.DataFrame({
    "Shooter": df["Shooter"],
    "TimeInGame": times
})
 

Мои шаги просто:

  1. Сравните столбцы h1…h5 со столбцом стрелка.
  2. Используя предыдущее сравнение, найдите значение времени в каждом столбце th1..th5.
  3. Создайте новый фрейм данных.