Найти разницу между 2 столбцами с пустыми значениями, используя панд
Я хочу найти разницу между 2 столбцами типа int в панде DataFrame. Я использую Python 2.7. Столбцы как ниже -
>>> df
INVOICED_QUANTITY QUANTITY_SHIPPED
0 15 NaN
1 20 NaN
2 7 NaN
3 7 NaN
4 7 NaN
Теперь я хочу вычесть QUANTITY_SHIPPED из INVOICED_QUANTITY, и я делаю следующее:
>>> df['Diff'] = df['QUANTITY_INVOICED'] - df['SHIPPED_QUANTITY']
>>> df
QUANTITY_INVOICED SHIPPED_QUANTITY Diff
0 15 NaN NaN
1 20 NaN NaN
2 7 NaN NaN
3 7 NaN NaN
4 7 NaN NaN
Как мне позаботиться о NaN? Я хотел бы получить приведенный ниже результат, поскольку я хочу, чтобы значения NaN рассматривались как 0 (ноль)-
>>> df
QUANTITY_INVOICED SHIPPED_QUANTITY Diff
0 15 NaN 15
1 20 NaN 20
2 7 NaN 7
3 7 NaN 7
4 7 NaN 7
Я не хочу делать df.fillna(0)
, В общем, я бы попробовал что-то вроде следующего и это работает, но не для разницы -
>>> df['Sum'] = df[['QUANTITY_INVOICED', 'SHIPPED_QUANTITY']].sum(axis=1)
>>> df
INVOICED_QUANTITY QUANTITY_SHIPPED Diff Sum
0 15 NaN NaN 15
1 20 NaN NaN 20
2 7 NaN NaN 7
3 7 NaN NaN 7
4 7 NaN NaN 7
3 ответа
Вы можете использовать sub
метод для вычитания - этот метод позволяет NaN
значения, которые будут рассматриваться как указанное значение:
df['Diff'] = df['INVOICED_QUANTITY'].sub(df['QUANTITY_SHIPPED'], fill_value=0)
Который производит:
INVOICED_QUANTITY QUANTITY_SHIPPED Diff
0 15 NaN 15
1 20 NaN 20
2 7 NaN 7
3 7 NaN 7
4 7 NaN 7
Другой удобный способ сделать это, как предлагает @JianxunLi: заполнить пропущенные значения в столбце (создав копию столбца) и вычесть как обычно.
Два подхода почти одинаковы, хотя sub
немного эффективнее, потому что не нужно заранее создавать копию столбца; он просто заполняет пропущенные значения "на лету":
In [46]: %timeit df['INVOICED_QUANTITY'] - df['QUANTITY_SHIPPED'].fillna(0)
10000 loops, best of 3: 144 µs per loop
In [47]: %timeit df['INVOICED_QUANTITY'].sub(df['QUANTITY_SHIPPED'], fill_value=0)
10000 loops, best of 3: 81.7 µs per loop
Я думаю, что простая заливка NaN 0 поможет вам.
df['Diff'] = df['INVOICED_QUANTITY'] - df['QUANTITY_SHIPPED'].fillna(0)
Out[153]:
INVOICED_QUANTITY QUANTITY_SHIPPED Diff
0 15 NaN 15
1 20 NaN 20
2 7 NaN 7
3 7 NaN 7
4 7 NaN 7
Решения, предложенные user3923281 и user5014134 , не работают должным образом, когда оба столбца имеют значение NaN. Вы можете немного пересмотреть это решение @Jianxun Li (за счет некоторого вычислительного времени), чтобы исправить это.
df['Diff'] = df['INVOICED_QUANTITY'].fillna(0) - df['QUANTITY_SHIPPED'].fillna(0)
Выкладываю несколько вариантов для сравнения:
data = {'C1': [1,2,np.nan,np.nan],
'C2': [6,np.nan,4,np.nan],
}
df = pd.DataFrame(data)
df['Dif']=df.C1-df.C2
df['Dif2']=df['C1'].sub(df['C2'], fill_value=0)
df['Dif3']=df['C1']-df['C2'].fillna(0)
df['Dif4']=df['C1'].fillna(0)-df['C2']
df['Dif5']=df['C1'].fillna(0)-df['C2'].fillna(0)
print (df)
который производит
C1 C2 Dif Dif2 Dif3 Dif4 Dif5
0 1.000 6.000 -5.000 -5.000 -5.000 -5.000 -5.000
1 2.000 NaN NaN 2.000 2.000 NaN 2.000
2 NaN 4.000 NaN -4.000 NaN -4.000 -4.000
3 NaN NaN NaN NaN NaN NaN 0.000