Pandas - заполнить новый столбец на основе существующих значений столбца - PullRequest
1 голос
/ 20 июня 2020

У меня есть следующий фрейм данных df_shots:

              TableIndex  MatchID  GameWeek           Player  ...      ShotPosition    ShotSide      Close             Position
ShotsDetailID                                                 ...                                                              
6                      5    46605         1  Roberto Firmino  ...  very close range         N/A      close  very close rangeN/A
8                      7    46605         1  Roberto Firmino  ...           the box  the centre  not close    the boxthe centre
10                     9    46605         1  Roberto Firmino  ...           the box    the left  not close      the boxthe left
17                    16    46605         1  Roberto Firmino  ...           the box  the centre      close    the boxthe centre
447                  446    46623         2  Roberto Firmino  ...           the box  the centre      close    the boxthe centre
...                  ...      ...       ...              ...  ...               ...         ...        ...                  ...
6656                6662    46870        27  Roberto Firmino  ...  very close range         N/A      close  very close rangeN/A
6666                6672    46870        27  Roberto Firmino  ...           the box   the right  not close     the boxthe right
6674                6680    46870        27  Roberto Firmino  ...           the box  the centre  not close    the boxthe centre
6676                6682    46870        27  Roberto Firmino  ...           the box    the left  not close      the boxthe left
6679                6685    46870        27  Roberto Firmino  ...   outside the box         N/A  not close   outside the boxN/A

Для ясности, все возможные значения «Position»:

positions = ['a difficult anglethe left',
             'a difficult anglethe right',
             'long rangeN/A',
             'long rangethe centre',
             'long rangethe left',
             'long rangethe right',
             'outside the boxN/A',
             'penaltyN/A',
             'the boxthe centre',
             'the boxthe left',
             'the boxthe right',
             'the six yard boxthe left',
             'the six yard boxthe right',
             'very close rangeN/A']

Теперь я бы сопоставил следующие значения x / y для каждого имени 'Position', сохраняя значение в новом столбце 'Position XY':

    the_boxthe_center = {'y':random.randrange(25,45), 'x':random.randrange(0,6)}
    the_boxthe_left = {'y':random.randrange(41,54), 'x':random.randrange(0,16)}
    the_boxthe_right = {'y':random.randrange(14,22), 'x':random.randrange(0,16)}
    very_close_rangeNA = {'y':random.randrange(25,43), 'x':random.randrange(0,4)}
    six_yard_boxthe_left = {'y':random.randrange(33,43), 'x':random.randrange(4,6)}
    six_yard_boxthe_right = {'y':random.randrange(25,33), 'x':random.randrange(4,6)}
    a_diffcult_anglethe_left = {'y':random.randrange(43,54), 'x':random.randrange(0,6)}
    a_diffcult_anglethe_right = {'y':random.randrange(14,25), 'x':random.randrange(0,6)}
    penaltyNA = {'y':random.randrange(36), 'x':random.randrange(8)}
    outside_the_boxNA = {'y':random.randrange(14,54), 'x':random.randrange(16,28)}
    long_rangeNA = {'y':random.randrange(0,68), 'x':random.randrange(40,52)}
    long_rangethe_centre = {'y':random.randrange(0,68), 'x':random.randrange(28,40)}
    long_rangethe_right = {'y':random.randrange(0,14), 'x':random.randrange(0,24)}
    long_rangethe_left = {'y':random.randrange(54,68), 'x':random.randrange(0,24)}

Я пробовал:

if df_shots['Position']=='very close rangeN/A':
        df_shots['Position X/Y']==very_close_rangeNA
...# and so on

Но я получить:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

Как мне это сделать?

Ответы [ 3 ]

1 голос
/ 20 июня 2020

Хранить так много связанных переменных вне контейнера - плохой трюк, давайте воспользуемся словарем, который мы сопоставляем с вашим фреймом данных.

data_dict = 
{'the boxthe centre': {'y':random.randrange(25,45)...}


df['Position'] = df['Position'].map(data_dict)

print(df['Position'])
6        {'y': 35, 'x': 2}
8        {'y': 32, 'x': 1}
10      {'y': 44, 'x': 11}
17       {'y': 32, 'x': 1}
447      {'y': 32, 'x': 1}
...                    NaN
6656     {'y': 35, 'x': 2}
6666    {'y': 15, 'x': 11}
6674     {'y': 32, 'x': 1}
6676    {'y': 44, 'x': 11}
6679    {'y': 37, 'x': 16}
Name: Position, dtype: object
0 голосов
/ 20 июня 2020

Вот пример кода, который выполняет то, что вы хотите. Я создал базовый c макет df_shots, но он должен работать так же на вашем большом DataFrame. Я также сохранил некоторые из этих бесплатных переменных в dict, чтобы упростить фильтрацию.

Следует отметить, что, поскольку вы предварительно вычисляете случайные значения positions_xy, все значения x / y будет одинаковым для каждой позиции выстрела. Это может быть, а может и не совпадать с вашими намерениями.

import pandas as pd
import random

# Sample df_shots
df_shots = pd.DataFrame({'Position': ['the_boxthe_center', 'the_boxthe_left']})

# Store position/xy pairs in dict
positions_xy = {'the_boxthe_center': {'y': random.randrange(25, 45), 'x': random.randrange(0, 6)},
                'the_boxthe_left': {'y': random.randrange(41, 54), 'x': random.randrange(0, 16)}}

# Create new column
df_shots['Position XY'] = ''

# Iterate over all position/xy pairs
for position, xy in positions_xy.items():
    # Determine indices of all players that match
    matches = df_shots['Position'] == position
    matches_indices = matches[matches].index
    # Update matching rows in df_shots with xy
    for idx in matches_indices:
        df_shots.at[idx, 'Position XY'] = xy

print(df_shots)

Вывод:

            Position        Position XY
0  the_boxthe_center  {'y': 36, 'x': 2}
1    the_boxthe_left  {'y': 44, 'x': 0}
0 голосов
/ 20 июня 2020

Вот фрагмент кода, который может помочь вам.

сначала создайте список всех ваших "Position XY", как

position_xy = [the_boxthe_center,the_boxthe_left,....,long_rangethe_left] #and so on...

и соответствующий positions list (как у вас уже есть), то я предлагаю вам создать словарь, чтобы каждая позиция выполняла вычисление соответствующей позиции xy

dict_positionxy = dict(zip(position, position_xy))

, затем вы создаете новый столбец в своем фреймворке данных, где вы хотите сохранить Значения x, y на основе позиции

 df_shots['Position X/Y'] = 0.

теперь вы l oop просматриваете все строки одну за другой

for index, row in df_shots.iterrows():
    for key, values in dict_positionxy.items():

       if row['Position'] == key:
           #row['Position X/Y'] = value
           df_shots.at[index,’Position X/Y’]= value

print(df_shots)

Это должно помочь :)

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