Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NaNs when subtracting dataframes pandas

I have two dataframes with only somewhat overlapping indices and columns.

old = pd.DataFrame(index = ['A', 'B', 'C'],
                   columns = ['k', 'l', 'm'],
                   data = abs(np.floor(np.random.rand(3, 3)*10)))

new = pd.DataFrame(index = ['A', 'B', 'C', 'D'],
                   columns = ['k', 'l', 'm', 'n'],
                   data = abs(np.floor(np.random.rand(4, 4)*10)))

I want to calculate the difference between them and tried

delta = new - old

This gives lots of NaNs where indices and columns do not match. I would like to treat the abscence of the indices and columns as zeroes, (old['n', 'D'] = 0). old will always be a subspace of new.

Any ideas?

EDIT: I guess I didn't explain it thoroughly enough. I don't want to fill the delta dataframe with zeroes. I want to treat missing indices and columns in old as if they were zeroes. I would then get the value in new['n', 'D'] in delta instead of a NaN.

like image 842
Marcus Högenå Bohman Avatar asked Nov 17 '16 12:11

Marcus Högenå Bohman


People also ask

Can I subtract two Dataframes pandas?

subtract() function is used for finding the subtraction of dataframe and other, element-wise. This function is essentially same as doing dataframe – other but with a support to substitute for missing data in one of the inputs.

How do I get rid of NaN in pandas?

By using dropna() method you can drop rows with NaN (Not a Number) and None values from pandas DataFrame. Note that by default it returns the copy of the DataFrame after removing rows. If you wanted to remove from the existing DataFrame, you should use inplace=True .

What does .values do to a DataFrame?

The values property is used to get a Numpy representation of the DataFrame. Only the values in the DataFrame will be returned, the axes labels will be removed. The values of the DataFrame. A DataFrame where all columns are the same type (e.g., int64) results in an array of the same type.


1 Answers

Use sub with fill_value=0:

In [15]:
old = pd.DataFrame(index = ['A', 'B', 'C'],
                   columns = ['k', 'l', 'm'],
                   data = abs(np.floor(np.random.rand(3, 3)*10)))
​
new = pd.DataFrame(index = ['A', 'B', 'C', 'D'],
                   columns = ['k', 'l', 'm', 'n'],
                   data = abs(np.floor(np.random.rand(4, 4)*10)))
delta = new.sub(old, fill_value=0)
delta

Out[15]:
   k  l  m  n
A  0  3 -9  7
B  0 -2  1  8
C -4  1  1  7
D  8  6  0  6
like image 80
EdChum Avatar answered Sep 18 '22 15:09

EdChum