3

I'm trying to multiply every 2nd row by -1 but in a specified column only. Using below, I'm hoping to multiply every 2nd row in column c by -1.

df = pd.DataFrame({  
    'a' : [2.0,1.0,3.5,2.0,5.0,3.0,1.0,1.0],
    'b' : [1.0,-1.0,3.5,3.0,4.0,2.0,3.0,2.0],     
    'c' : [2.0,2.0,2.0,2.0,-1.0,-1.0,-2.0,-2.0],                  
    })

df['c'] = df['c'][::2] * -1

Intended output:

     a    b    c
0  2.0  1.0  2.0
1  1.0 -1.0 -2.0
2  3.5  3.5  2.0
3  2.0  3.0 -2.0
4  5.0  4.0 -1.0
5  3.0  2.0  1.0
6  1.0  3.0 -2.0
7  1.0  2.0  2.0
Chopin
  • 96
  • 1
  • 10
  • 35
  • Does this answer your question? [Python: Pandas Dataframe how to multiply entire column with a scalar](https://stackoverflow.com/questions/33768122/python-pandas-dataframe-how-to-multiply-entire-column-with-a-scalar) – ddejohn Feb 16 '21 at 07:29
  • The current top answer in this thread is a simple modification of the techniques in that thread I linked. – ddejohn Feb 16 '21 at 07:36
  • @Chopin - No, it is not dupe. If closed, let me know for reopen. – jezrael Feb 16 '21 at 07:37
  • @blorgon, Think you're embellishing a tad. – Chopin Feb 16 '21 at 07:38
  • Chopin is correct, this isn't an exact duplicate and should be left open. @blorgon: the missing part is the `[1::2]` odd-row -onlyindexing as jezrael shows. – smci Feb 16 '21 at 07:47

5 Answers5

6

One way using pandas.DataFrame.update:

df.update(df['c'][1::2] * -1)
print(df)

Output:

     a    b    c
0  2.0  1.0  2.0
1  1.0 -1.0 -2.0
2  3.5  3.5  2.0
3  2.0  3.0 -2.0
4  5.0  4.0 -1.0
5  3.0  2.0  1.0
6  1.0  3.0 -2.0
7  1.0  2.0  2.0
Chris
  • 29,127
  • 3
  • 28
  • 51
4

Use DataFrame.iloc for slicing with Index.get_loc for position of column c:

df.iloc[1::2, df.columns.get_loc('c')] *= -1
#working same like
#df.iloc[1::2, df.columns.get_loc('c')] = df.iloc[1::2, df.columns.get_loc('c')] * -1

Or use DataFrame.loc with select values in df.index:

df.loc[df.index[1::2], 'c'] *= -1

Or:

df.loc[df.index % 2 == 1, 'c'] *= -1

print (df)
    
     a    b    c
0  2.0  1.0  2.0
1  1.0 -1.0 -2.0
2  3.5  3.5  2.0
3  2.0  3.0 -2.0
4  5.0  4.0 -1.0
5  3.0  2.0  1.0
6  1.0  3.0 -2.0
7  1.0  2.0  2.0
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
0

Or you can write your own function:

def multiple(df):
    new_df = pd.DataFrame()
    for i in range(0, len(df)):
        if i // 2 == 0:
            new_row = pd.DataFrame(data = df.iloc[i]*(-1)).T      
            new_df = new_df.append(new_row, ignore_index=True)
        else:
            new_row = pd.DataFrame(data = df.iloc[i]).T      
            new_df = new_df.append(new_row, ignore_index=True)            

        i+=1
        
    return new_df
vojtam
  • 1,157
  • 9
  • 34
0

You can use divmod with a series:

s = 2*np.arange(len(df))%2 - 1
df["c"] = -df.c*s

     a    b    c
0  2.0  1.0  2.0
1  1.0 -1.0 -2.0
2  3.5  3.5  2.0
3  2.0  3.0 -2.0
4  5.0  4.0 -1.0
5  3.0  2.0  1.0
6  1.0  3.0 -2.0
7  1.0  2.0  2.0
anon01
  • 10,618
  • 8
  • 35
  • 58
0

You can use this code :

     a    b    c
0  2.0  1.0  2.0
1  1.0 -1.0  2.0
2  3.5  3.5  2.0
3  2.0  3.0  2.0
4  5.0  4.0 -1.0
5  3.0  2.0 -1.0
6  1.0  3.0 -2.0
7  1.0  2.0 -2.0
df.loc[df.index % 2 == 1, "c" ] = df.c * - 1
     a    b    c
0  2.0  1.0  2.0
1  1.0 -1.0 -2.0
2  3.5  3.5  2.0
3  2.0  3.0 -2.0
4  5.0  4.0 -1.0
5  3.0  2.0  1.0
6  1.0  3.0 -2.0
7  1.0  2.0  2.0