for example I have a dataframe:
0 | 1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|---|
0 | 0.493212 | 0.586246 | nan | 0.589289 | nan | 0.629087 | 0.593872 |
1 | 0.568513 | 0.367722 | nan | nan | nan | nan | 0.423369 |
2 | 0.70054 | 0.735529 | nan | nan | 0.494135 | nan | nan |
3 | nan | nan | nan | 0.338822 | 0.466331 | 0.765367 | 0.83082 |
4 | 0.512891 | nan | 0.623782 | 0.642438 | nan | 0.541117 | 0.92981 |
If I compare it like:
df >= 0.5
The result is:
0 | 1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|---|
0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 |
1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
3 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
4 | 1 | 0 | 1 | 1 | 0 | 1 | 1 |
How can I keep nan cell ? I mean I need 0.5 > np.nan == np.nan
not 0.5 > np.nan == False
CodePudding user response:
IIUC, you can use a mask
:
df.lt(0.5).astype(int).mask(df.isna())
output:
0 1 2 3 4 5 6
0 1.0 0.0 NaN 0.0 NaN 0.0 0.0
1 0.0 1.0 NaN NaN NaN NaN 1.0
2 0.0 0.0 NaN NaN 1.0 NaN NaN
3 NaN NaN NaN 1.0 1.0 0.0 0.0
4 0.0 NaN 0.0 0.0 NaN 0.0 0.0
If you want to keep the integer type:
out = df.lt(0.5).astype(pd.Int64Dtype()).mask(df.isna()))
output:
0 1 2 3 4 5 6
0 1 0 <NA> 0 <NA> 0 0
1 0 1 <NA> <NA> <NA> <NA> 1
2 0 0 <NA> <NA> 1 <NA> <NA>
3 <NA> <NA> <NA> 1 1 0 0
4 0 <NA> 0 0 <NA> 0 0
CodePudding user response:
Use DataFrame.mask
with convert values to integers:
df = (df >= 0.5).astype(int).mask(df.isna())
print (df)
0 1 2 3 4 5 6
0 0.0 1.0 NaN 1.0 NaN 1.0 1.0
1 1.0 0.0 NaN NaN NaN NaN 0.0
2 1.0 1.0 NaN NaN 0.0 NaN NaN
3 NaN NaN NaN 0.0 0.0 1.0 1.0
4 1.0 NaN 1.0 1.0 NaN 1.0 1.0
Details:
print ((df >= 0.5).astype(int))
0 1 2 3 4 5 6
0 0 1 0 1 0 1 1
1 1 0 0 0 0 0 0
2 1 1 0 0 0 0 0
3 0 0 0 0 0 1 1
4 1 0 1 1 0 1 1
Another idea with numpy.select
:
df[:] = np.select([df.isna(), df >= 0.5], [None, 1], default=0)
print (df)
0 1 2 3 4 5 6
0 0.0 1.0 NaN 1.0 NaN 1.0 1.0
1 1.0 0.0 NaN NaN NaN NaN 0.0
2 1.0 1.0 NaN NaN 0.0 NaN NaN
3 NaN NaN NaN 0.0 0.0 1.0 1.0
4 1.0 NaN 1.0 1.0 NaN 1.0 1.0
Btw, if need True/False
with NaN
is possible use Nullable Boolean data type
:
df = (df >= 0.5).astype(int).mask(df.isna()).astype('boolean')
print (df)
0 1 2 3 4 5 6
0 False True <NA> True <NA> True True
1 True False <NA> <NA> <NA> <NA> False
2 True True <NA> <NA> False <NA> <NA>
3 <NA> <NA> <NA> False False True True
4 True <NA> True True <NA> True True