How to overwrite multiple rows from one row (iloc/loc difference)?

Issue

I have a dataframe and would like to assign multiple values from one row to multiple other rows.
I get it to work with .iloc but for some when I use conditions with .loc it only returns nan.

df = pd.DataFrame(dict(A = [1,2,0,0],B=[0,0,0,10],C=[3,4,5,6]))
df.index = ['a','b','c','d']

When I use loc with conditions or with direct index names:

df.loc[df['A']>0, ['B','C']] = df.loc['d',['B','C']]
df.loc[['a','b'], ['B','C']] = df.loc['d',['B','C']]

it will return

     A       B       C
a   1.0     NaN     NaN
b   2.0     NaN     NaN
c   0.0     0.0     5.0
d   0.0     10.0    6.0

but when I use .iloc it actually works as expected

df.iloc[0:2,1:3] = df.iloc[3,1:3]
    A   B   C
a   1   10  6
b   2   10  6
c   0   0   5
d   0   10  6

is there a way to do this with .loc or do I need to rewrite my code to get the row numbers from my mask?

Solution

When you use labels, pandas perform index alignment, and in your case there is no common indices thus the NaNs, while location based indexing does not align.

You can assign a numpy array to prevent index alignment:

df.loc[['a','b'], ['B','C']] = df.loc['d',['B','C']].values

output:

   A   B  C
a  1  10  6
b  2  10  6
c  0   0  5
d  0  10  6

Answered By – mozway

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published