Hendrik Wiese
Hendrik Wiese

Reputation: 2219

Pandas: merge two dataframes ignoring NaN

Assume I have the following two DataFrames:

  X    Y    Z
1 0.0  0.0  0.0
2 1.0  2.0  3.0
3 4.0  2.0  0.0
4 NaN  NaN  NaN
5 NaN  NaN  NaN
6 NaN  NaN  NaN
7 NaN  NaN  NaN
8 NaN  NaN  NaN

and

  X.2  Y.2  Z.2
1 NaN  NaN  NaN
2 NaN  NaN  NaN
3 NaN  NaN  NaN
4 NaN  NaN  NaN
5 NaN  NaN  NaN
6 9.0  3.0  6.0
7 7.0  4.0  3.0
8 3.0  6.0  8.0

I would like to fill the missing data in the first DataFrame with the values from the second. Result should look like this:

  X    Y    Z
1 0.0  0.0  0.0
2 1.0  2.0  3.0
3 4.0  2.0  0.0
4 NaN  NaN  NaN
5 NaN  NaN  NaN
6 9.0  3.0  6.0
7 7.0  4.0  3.0
8 3.0  6.0  8.0

If possible I'd like to avoid creating a new DataFrame but fill up the first DataFrame in place.

How do I do this?

Upvotes: 7

Views: 4568

Answers (4)

Colonel Beauvel
Colonel Beauvel

Reputation: 31181

You can proceed simply with update which fills up the first dataframe df1 based on the value of df2:

df2.columns = df1.columns

df1.update(df2)

In [118]: df1
Out[118]:
    X   Y   Z
1   0   0   0
2   1   2   3
3   4   2   0
4 NaN NaN NaN
5 NaN NaN NaN
6   9   3   6
7   7   4   3
8   3   6   8

Upvotes: 8

iayork
iayork

Reputation: 6709

If you line the columns up, then fillna() will do this:

df2.columns = df1.column
df1.fillna(df2, inplace=True)
df1

    X   Y   Z
1   0   0   0
2   1   2   3
3   4   2   0
4 NaN NaN NaN
5 NaN NaN NaN
6   9   3   6
7   7   4   3
8   3   6   8

Upvotes: 1

LetzerWille
LetzerWille

Reputation: 5668

with python if dataframe could be list of lists

d1 =[[1,0.0, 0.0, 0.0],
    [2,1.0, 2.0, 3.0],
    [3,4.0, 2.0, 0.0],
    [4,'NaN', 'NaN', 'NaN'],
    [5,'NaN', 'NaN', 'NaN'],
    [6,'NaN', 'NaN', 'NaN'],
    [7,'NaN', 'NaN', 'NaN'],
    [8,'NaN', 'NaN', 'NaN']]


d2 = [[1,'NaN', 'NaN', 'NaN'],
    [2,'NaN', 'NaN', 'NaN'],
    [3,'NaN', 'NaN', 'NaN'],
    [4,'NaN', 'NaN', 'NaN'],
    [5,'NaN', 'NaN', 'NaN'],
    [6,9.0, 3.0, 6.0],
    [7,7.0, 4.0, 3.0],
    [8,3.0, 6.0, 8.0]]


def replace_row(l,ln):

    for i, el in enumerate(l):
        if el  == 'NaN':
            l[i] = ln[i]


for i,l1 in enumerate(d1):
    for j, l2 in enumerate(d2):
        if i == j:
            replace_row(l1,l2)


for el in d1:
    print(el)

result in:

[1, 0.0, 0.0, 0.0]
[2, 1.0, 2.0, 3.0]
[3, 4.0, 2.0, 0.0]
[4, 'NaN', 'NaN', 'NaN']
[5, 'NaN', 'NaN', 'NaN']
[6, 9.0, 3.0, 6.0]
[7, 7.0, 4.0, 3.0]
[8, 3.0, 6.0, 8.0]

Upvotes: 0

Alex
Alex

Reputation: 826

If you rename the columns of your second dataframe you can then use the concat and groupby like this :

In[96]: df1
Out[96]: 
    X   Y   Z
1   0   0   0
2   1   2   3
3   4   2   0
4 NaN NaN NaN
5 NaN NaN NaN
6 NaN NaN NaN
7 NaN NaN NaN
8 NaN NaN NaN

In[101]: df2
Out[101]: 
    X   Y   Z
1 NaN NaN NaN
2 NaN NaN NaN
3 NaN NaN NaN
4 NaN NaN NaN
5 NaN NaN NaN
6   9   3   6
7   7   4   3
8   3   6   8

In[102]: pd.concat([df1,df2]).groupby(level=0).sum()
Out[102]: 
    X   Y   Z
1   0   0   0
2   1   2   3
3   4   2   0
4 NaN NaN NaN
5 NaN NaN NaN
6   9   3   6
7   7   4   3
8   3   6   8

Upvotes: 0

Related Questions