Home > Software design >  looping through a data frame Python
looping through a data frame Python

Time:12-03

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?

CodePudding user response:

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-conditionnal 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

CodePudding user response:

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
  • Related