Pandas сумма двух столбцов - правильная работа с нанозначениями - PullRequest
2 голосов
/ 06 мая 2020

При суммировании двух pandas столбцов я хочу игнорировать nan-значения, когда один из двух столбцов является плавающим. Однако, когда nan появляется в обоих столбцах, я хочу сохранить nan в выводе (вместо 0,0).

Исходный фрейм данных:

Surf1     Surf2
0         0
NaN       8
8         15
NaN       NaN
16        14
15        7

Желаемый вывод:

Surf1     Surf2     Sum
0         0         0
NaN       8         8
8         15        23
NaN       NaN       NaN
16        14        30
15        7         22

Пробный код: -> приведенный ниже код игнорирует нан-значения, но при взятии суммы двух нан-значений на выходе он дает 0,0, где Я хочу сохранить его как NaN в этом конкретном случае, чтобы эти пустые значения были отделены от значений, которые фактически равны 0 после суммирования.

import pandas as pd
import numpy as np

data = pd.DataFrame({"Surf1": [10,np.nan,8,np.nan,16,15], "Surf2": [22,8,15,np.nan,14,7]})
print(data)

data.loc[:,'Sum'] = data.loc[:,['Surf1','Surf2']].sum(axis=1)
print(data)

Ответы [ 4 ]

3 голосов
/ 06 мая 2020

Из документации pandas .DataFrame.sum

По умолчанию сумма пустых серий или серий полностью NA равна 0.

>>> pd.Series ([]). sum () # min_count = 0 - значение по умолчанию 0.0

Этим можно управлять с помощью параметра min_count. Например, если вы хотите, чтобы сумма пустого ряда была NaN, передайте min_count = 1.

Измените свой код на

data.loc[:,'Sum'] = data.loc[:,['Surf1','Surf2']].sum(axis=1, min_count=1)

output

   Surf1  Surf2
0   10.0   22.0
1    NaN    8.0
2    8.0   15.0
3    NaN    NaN
4   16.0   14.0
5   15.0    7.0
   Surf1  Surf2   Sum
0   10.0   22.0  32.0
1    NaN    8.0   8.0
2    8.0   15.0  23.0
3    NaN    NaN   NaN
4   16.0   14.0  30.0
5   15.0    7.0  22.0
3 голосов
/ 06 мая 2020

Вы можете mask результат, выполнив:

df.sum(1).mask(df.isna().all(1))

0     0.0
1     8.0
2    23.0
3     NaN
4    30.0
5    22.0
dtype: float64
2 голосов
/ 06 мая 2020

Вы можете использовать min_count, это будет суммировать всю строку, если есть хотя бы ненулевое значение, если все null вернут null

df['SUM']=df.sum(min_count=1,axis=1)
#df.sum(min_count=1,axis=1)
Out[199]: 
0     0.0
1     8.0
2    23.0
3     NaN
4    30.0
5    22.0
dtype: float64
1 голос
/ 06 мая 2020

Вы можете сделать:

df['Sum'] = df.dropna(how='all').sum(1)

Вывод:

   Surf1  Surf2   Sum
0   10.0   22.0  32.0
1    NaN    8.0   8.0
2    8.0   15.0  23.0
3    NaN    NaN   NaN
4   16.0   14.0  30.0
5   15.0    7.0  22.0
...