1

I am trying to write a for loop with an if statement which iterates through the columns and performs some multiplication creating a new column in the dataframe.

So far I have achieved this, but it is clearly wrong ad no columns are actually generated. Any hints or suggestions is highly appreciated!

for i in df[1:]:
    if  i == 'a' or i == 'b' or i == 'b':
        data[i] = df[i]* 4
    elif i == 'CZK_fwdp':
        data[i] = df[i]* 7
    else:
        data[i] = df[i]* 5
break    
jar
  • 2,646
  • 1
  • 22
  • 47
clu
  • 117
  • 1
  • 6
  • Your first problem is you're setting a value on a slice of the dataframe, not the original dataframe itself. See [this question](https://stackoverflow.com/questions/52301336/pandas-assign-a-value-to-a-cell-why-does-this-not-work/52301385#52301385). – Jake Morris Oct 18 '18 at 13:17
  • If comment from Jake helps then good, otherwise suggest you to post sample df also!! – Rahul Agarwal Oct 18 '18 at 13:19
  • 1
    Can you include a sample of your desired output? – iDrwish Oct 18 '18 at 13:19
  • @JakeMorris The first problem is probably using a `for `loop to begin with – DeepSpace Oct 18 '18 at 13:19
  • 1
    As of now this is an [XY](http://xyproblem.info/) problem. Ask about your problem, not about an attempted solution – DeepSpace Oct 18 '18 at 13:20
  • @DeepSpace I agree it's bad practice, however the code should still run with a `for` loop. `apply` would be better. – Jake Morris Oct 18 '18 at 14:59

3 Answers3

1

I've created an example how I usually do same tasks:

df = pd.DataFrame({'a': [1,1,1], 'b': [1,2,3], 'c': [0,-1,-2]})
print(df)
Out:
   a  b  c
0  1  1  0
1  1  2 -1
2  1  3 -2

This is sample dataframe. You can apply some function to modify all it's columns depending on column's name, available throgh name attribute. For example, column 'a' has just name a:

df['a'].name
Out:
'a'

def mapper(name):
    return name + '_new'


df_new = df.apply(lambda col: col * 4 if col.name == 'a' or col.name == 'b' 
         else col * 7 if col.name == 'CZK_fwdp' 
         else col * 5, axis=0).rename(mapper=mapper, axis=1)
print(df_new)
Out:
   a_new  b_new  c_new
0      4      4      0
1      4      8     -5
2      4     12    -10

Use apply method to apply you lambda function along the columns with argument axis=1. Function mapper is used to avoid column's names interference. To get desired dataframe, you can just concatente old and new dataframes:

df_conc = pd.concat((df, df_new), axis=1)
print(df_conc)
Out:
   a  b  c  a_new  b_new  c_new
0  1  1  0      4      4      0
1  1  2 -1      4      8     -5
2  1  3 -2      4     12    -10

If you don't like lambda functions, you can use common function:

def modify_column(col):
    if col.name == 'a' or col.name == 'b':
        return col * 4
    elif col.name == 'CZK_fwdp':
        return col * 7
    else:
        return col * 5

df_new = df.apply(modify_column, axis=0).rename(mapper=mapper, axis=1)
Mikhail Stepanov
  • 3,680
  • 3
  • 23
  • 24
  • @clu there was an error in my answer, so I've justs change `axis=1` in `apply` to `axis=0`. Now it's correct! The rest of the answer remains the same. – Mikhail Stepanov Oct 18 '18 at 15:16
0

Could you give us the code which defines the variable df please?

Remember that a data frame is a little bit more complicated than a list. You have to specify the column on which you want to work with (see the documentation).

The first line of your code should probably be replaced by something like:

for i in df['name_of_your_column']:
Adil B
  • 14,635
  • 11
  • 60
  • 78
dallonsi
  • 1,299
  • 1
  • 8
  • 29
0

Its a dataframe so you could do something like below

for _, row in df.iterrows():
    if  row['col1'] == 'a' or row['col1'] == 'b' or row['col1'] == 'c':
        row['col1'] = row['col1']* 4
    elif row['col1'] == 'CZK_fwdp':
        row['col1'] = row['col1']* 7
    else:
        row['col1'] = row['col1']* 5
ansu5555
  • 416
  • 2
  • 7