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
isname
(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'))