1

I have this data frame where I sliced columns from the original data frame:

Type 1      Attack 
Grass         62
Grass         82
Dragon       100
Fire          52
Rock         100

I want to create each Pokemon’s adjusted attack attribute against grass Pokemon based on ‘Type 1’ where;

  • the attack attribute is doubled if grass Pokemon are bad against that type
  • halved if they are good against that type
  • else remains the same.

I have looping through the data:

grass_attack = []
for value in df_["Type 1"]:
    if value ==["Type 1 == Fire"] or value==["Type 1 == Flying"] or value==["Type 1 == Poison"] or value==["Type 1 == Bug"] or value==["Type1== Steel"] or value ==["Type 1 == Grass"] or value ==["Type 1 == Dragon"]:
        result.append(df_["Attack"]/2)
    elif value==["Type 1==Ground"] or value==["Type1== Ground"] or value==["Type 1 == Water"]:
    
        grass_attack.append(df_["Attack"]*2)
    else:
        grass_attack.append(df_["Attack"])

df_["grass_attack"] = grass_attack  
print(df_)

but I got some crazy results after this. How can I efficiently loop through a data frame's column in order to adjust another column?

or is there another way to do this?

1
  • 1
    value ==["Type 1 == Fire"] this has no sense at all, how a value of a column (a string) would be equal to a list of one string, that contains some equality Commented Dec 2, 2022 at 13:10

2 Answers 2

2

You could use apply to do the necessary calculations. In the following code, the modify_Attack() function is used to calculate the Grass Attack values based on the Type1 and Attack values.

  • Type 1 values that are in the bad list will have their attack values halved.
  • Type 1 values that are in the good list will have their attack values doubled.
  • All other attack values will remain unchanged.

Here is the code:

import pandas as pd

# Create dataframe
df = pd.DataFrame({ 'Type 1': ['Grass', 'Grass', 'Dragon', 'Fire', 'Rock'],
                    'Attack': [62, 82, 100, 52, 100]})


# Function to modify the Attack value based on the Type 1 value
def modify_Attack(type_val, attack_val):
    bad = ['Fire', 'Flying', 'Poison', 'Bug', 'Steel', 'Grass', 'Dragon']
    good = ['Ground','Water']
    
    result = attack_val # default value is unchanged
    
    if type_val in bad:
        result /= 2

    elif type_val in good:
        result *= 2
    
    return result
        

# Create the Grass Attack column
df['Grass Attack'] = df.apply(lambda x: modify_Attack(x['Type 1'], x['Attack']), axis=1).astype(int)

# print the dataframe
print(df)

OUTPUT:

   Type 1  Attack  Grass Attack
0   Grass      62            31
1   Grass      82            41
2  Dragon     100            50
3    Fire      52            26
4    Rock     100           100
Sign up to request clarification or add additional context in comments.

Comments

2

There is some issues with your code as @azro pointed in the comments and there is no need for a loop here. You can simply use numpy.select to create a multi-conditional column.

Here is an example to give you the general logic :

df["Attack"] = df["Attack"].astype(int)
    
conditions = [df["Type 1"].eq("Grass"), df["Type 1"].isin(["Fire", "Rock"])]
choices = [df["Attack"].div(2), df["Attack"].mul(2)]
    
df["grass_attack"] = np.select(conditions, choices, default=df["Attack"]).astype(int)

Output

print(df)

   Type 1  Attack  grass_attack
0   Grass      62            31
1   Grass      82            41
2  Dragon     100           100
3    Fire      52           104
4    Rock     100           200

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.