I am having trouble finding a way to do an efficient element-wise minimum of two Series objects in pandas. For example I can add two Series easily enough:
In
pd.Series([1,2,3,4,5]).clip(upper=pd.Series([6,5,4,3,2]))
will get you:
0 1
1 2
2 3
3 3
4 2
dtype: int64
You can concat the dataframes and take the minimum, specifying level=0
:
>>> s1 = pd.Series(data=[1,1,1], index=[1,2,3])
>>> s2 = pd.Series(data=[1,2,2,1], index=[1,2,3,4])
>>> pd.concat([s1, s2]).min(level=0)
1 1
2 1
3 1
4 1
dtype: int64
This approach also works on dataframes.
Another similar way:
In [11]: pd.DataFrame([s1, s2]).min()
Out[11]:
1 1
2 1
3 1
4 1
dtype: float64
You can use the combine
method of a DataFrame with np.minimum
as the argument. np.minimum
has special handling for NaN and complex NaNs.
Indeed, the pandas docs for combine uses the np.minimum
function to illustrate a "true element-wise combine":
>>> df1 = pd.DataFrame({'A': [5, 0], 'B': [2, 4]})
>>> df2 = pd.DataFrame({'A': [1, 1], 'B': [3, 3]})
>>> df1.combine(df2, np.minimum)
A B
0 1 2
1 0 3
Same answer as Andy Hayden, but a bit easier to read:
>>> import pandas as pd
>>> s1 = pd.Series(data=[1,2,3,4,5], index=[1,2,3,4,5])
>>> s2 = pd.Series(data=[5,1,3,5], index=[1,2,3,4])
>>> pd.DataFrame([s1, s2]).min()
1 1.0
2 1.0
3 3.0
4 4.0
5 5.0
dtype: float64
I find this the simplest:
import numpy as np
smax = np.minimum(s1, s2)
Link to docs (numpy.minimum)