Home > Blockchain >  What is the best way to move values around in Pandas?
What is the best way to move values around in Pandas?

Time:04-15

I'm trying to move some values around. My idea is that I'm trying to create a function where you send a name into it and it prints out all your matchups from the csv files. That's working so far but what I really want is the aforementioned name in one column and their opponents in another.

Here's what I have so far but I can't seem to figure out where I'm going wrong.

def get_matchups_by_name(name):
    df = PD_MATCHUPS
    df = df[(df['Team 1 Name'] == name) | (df['Team 2 Name'] == name)] # Getting rows which include the correct name
    if df['Team 1 Name'].str.contains(name).any():
        df['Team'] = df['Team 1 Name']
        df['Opponent'] = df['Team 2 Name']
        df['Score'] = df['Team 1 Pts']
        df['Opp Score'] = df['Team 2 Pts']
    elif df['Team 2 Name'].str.contains(name).any():
        df['Team'] = df['Team 2 Name']
        df['Opponent'] = df['Team 1 Name']
        df['Score'] = df['Team 2 Pts']
        df['Opp Score'] = df['Team 1 Pts']
    return df[['Week', 'Team', 'Score', 'Opp Score', 'Opponent']]

print(get_matchups_by_name('Dagur'))

Printing this spits out:

    Week      Team   Score  Opp Score  Opponent
4      1     Dagur  120.65     105.40    Knútur
9      2       Óli  140.65     155.00     Dagur
16     3     Dagur  103.15      95.75   Brynjar
18     4     Björn   96.00     110.60     Dagur
28     5     Dagur   92.25     154.70      Aron

Here's what I want it to look like for everyone, using another name for this example:

print(get_matchups_by_name('Björn'))
    Week   Team   Score  Opp Score  Opponent
0      1  Björn   86.95      76.80      Tóti
6      2  Björn  150.25     106.25      Aron
12     3  Björn  129.65      63.80  Eyjólfur
18     4  Björn   96.00     110.60     Dagur
24     5  Björn   99.10     138.05   Brynjar
...
94    17  Björn  136.60     125.80      Tóti

Finally just to show what the data looks like originally:

    Week Team 1 Name  Team 1 Pts  Team 2 Pts Team 2 Name   Diff
0      1       Björn       86.95       76.80        Tóti  10.15
1      1      Steini      155.95      157.45    Haraldur   1.50
2      1         Óli      113.50      102.55     Brynjar  10.95
3      1    Eyjólfur      110.05      119.95        Aron   9.90
4      1       Dagur      120.65      105.40      Knútur  15.25

CodePudding user response:

I made it work with this:

def get_matchups_by_name(name):
    df = PD_MATCHUPS
    df = df[(df['Team 1 Name'] == name) | (df['Team 2 Name'] == name)] # Filtering out rows which only include the name
    df.loc[df['Team 1 Name'] == name, 'Team'] = name
    df.loc[df['Team 1 Name'] == name, 'Score'] = df['Team 1 Pts']
    df.loc[df['Team 2 Name'] == name, 'Team'] = name
    df.loc[df['Team 2 Name'] == name, 'Score'] = df['Team 2 Pts']
    df.loc[df['Team 1 Name'] != name, 'Opponent'] = df['Team 1 Name']
    df.loc[df['Team 1 Name'] != name, 'Opp Score'] = df['Team 1 Pts']
    df.loc[df['Team 2 Name'] != name, 'Opponent'] = df['Team 2 Name']
    df.loc[df['Team 2 Name'] != name, 'Opp Score'] = df['Team 2 Pts']
    return df[['Week', 'Team', 'Score', 'Opp Score', 'Opponent']]

Which just looks like a really convoluted and bad way to achieve it. Also the terminal is just screaming at me with these warnings:

/opt/homebrew/lib/python3.9/site-packages/pandas/core/indexing.py:1684: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  self.obj[key] = infer_fill_value(value)
/opt/homebrew/lib/python3.9/site-packages/pandas/core/indexing.py:1817: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  self._setitem_single_column(loc, value, pi)
/opt/homebrew/lib/python3.9/site-packages/pandas/core/indexing.py:1681: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  self.obj[key] = empty_value
/opt/homebrew/lib/python3.9/site-packages/pandas/core/indexing.py:1773: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  self._setitem_single_column(ilocs[0], value, pi)

If anyone finds a better way to do this, please let me know.

CodePudding user response:

You can use np.where here. I tried with df.where, but it didn't work very well in this instance (from what I tried at least), so the slightly more confusing np.where it was!

The np.where is as follows:

  • If Team 1 Name is name (True/False)...
  • Then return week, team 1 name, team 1 pts, team 2 pts, team 2 name
  • Else return week, team 2 name, team 2 pts, team 1 pts, team 1 name
  • Returns an array

A dataframe is then created using this array, where the desired column names are given.

import pandas as pd
import numpy as np

PD_MATCHUPS = pd.read_csv("Data.csv", header=0)

def get_matchups_by_name(name):
    df = PD_MATCHUPS.copy()
    df = df[(df['Team 1 Name'] == name) | (df['Team 2 Name'] == name)]
    
    array = np.where(df["Team 1 Name"] == name,
                   [df["Week"], df["Team 1 Name"], df["Team 1 Pts"], df["Team 2 Pts"], df["Team 2 Name"]],
                   [df["Week"], df["Team 2 Name"], df["Team 2 Pts"], df["Team 1 Pts"], df["Team 1 Name"]])
    matches = pd.DataFrame({'Week': array[0], 'Team': array[1], 'Score': array[2],
                            'Opp Score': array[3], 'Opponent': array[4]})
    
    return matches

print(get_matchups_by_name('Björn'))
  • Related