DataFrame型のsum関数を使うときにaxis=0より列ごとの合計になると思うのですが列にNaNが存在していた時に答えはその部分を0として計算した結果となります。値同士を足し合わせると答えはNaNとなります。なぜNaNの場所は0として計算されるのでしょうか。
仮説としては数字のsum関数が数字のみを足し合わせる関数なのではないかです。
是非回答お願いします。
下のコードはNaNを含むDataFrame型のものをsum関数で計算したものと要素同士で足し合わせたものです。
Python
1>>> import numpy as np 2>>> from pandas import DataFrame 3>>> a = DataFrame(np.array([[1,2,np.nan],[np.nan,3,4]]),columns=['A','B','C'],index=['a','b']) 4>>> a 5 A B C 6a 1.0 2.0 NaN 7b NaN 3.0 4.0 8>>> a.sum() 9A 1.0 10B 5.0 11C 4.0 12dtype: float64 13>>> a.loc['a','A']+a.loc['b','A'] 14nan 15
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答8件
0
sum() はデフォルト (skipna=True
) では、NaN は無視して、NaN 以外を足し合わせた結果を返します。
skipna=False
を指定すると、NaN が含まれる場合は結果も NaN になります。
ドキュメントを参照ください。
pandas.Series.sum — pandas 1.0.3 documentation
skipnabool, default True
Exclude NA/null values when computing the result.
python
1import pandas as pd 2 3a = pd.Series([1, 2, 3, None]) 4print(a.sum()) # 6.0 5print(a.sum(skipna=False)) # nan
投稿2020/04/26 16:28
総合スコア21956
0
既に回答は上がっていますし、sum()のドキュメントにも記述があるようですが、僕はちゃんと理由を突き止めたいので、ソースをいつも確認します。
PyCharmなどIDEを使っていれば、.sum()の定義へ簡単に飛べますので、答えにたどり着くまで探します。(バイナリのモジュールにたどり着いてソースが不明なこともありますが)
Python3
1print(a.sum())
のsum()は関数を作る関数で定義されてる様子。
Python3
1# pandas/core/generic.py 2 cls.sum = _make_min_count_stat_function( 3 cls, 4 "sum", 5 name, 6 name2, 7 axis_descr, 8 """Return the sum of the values for the requested axis.\n 9 This is equivalent to the method ``numpy.sum``.""", 10 nanops.nansum, 11 _stat_func_see_also, 12 _sum_examples, 13 )
nanops.nansumと言ういかにもな引数がありますから、さらに辿ると、
Python3
1# pandas/core/nanops.py 2 3@disallow("M8") 4def nansum(values, axis=None, skipna=True, min_count=0, mask=None): 5 """ 6 Sum the elements along an axis ignoring NaNs 7 8 Parameters 9 ---------- 10 values : ndarray[dtype] 11 axis: int, optional 12 skipna : bool, default True 13 min_count: int, default 0 14 mask : ndarray[bool], optional 15 nan-mask if known 16 17 Returns 18 ------- 19 result : dtype 20 21 Examples 22 -------- 23 >>> import pandas.core.nanops as nanops 24 >>> s = pd.Series([1, 2, np.nan]) 25 >>> nanops.nansum(s) 26 3.0 27 """ 28 values, mask, dtype, dtype_max, _ = _get_values( 29 values, skipna, fill_value=0, mask=mask 30 ) 31 dtype_sum = dtype_max 32 if is_float_dtype(dtype): 33 dtype_sum = dtype 34 elif is_timedelta64_dtype(dtype): 35 dtype_sum = np.float64 36 the_sum = values.sum(axis, dtype=dtype_sum) 37 the_sum = _maybe_null_out(the_sum, axis, mask, values.shape, min_count=min_count) 38 39 return _wrap_results(the_sum, dtype) 40
とあり、ignoring NaNsと言うことでNaNは敢えて無視しています。
_get_valuesではmaskと言う入力したaと同じサイズの行列を作り、NaNに対してはTrueそれ以外はFalseをセットし、最後にnp.putmaskでmaskがTrueの要素は強制的に0にした値をnansumに返しています。Numpyにputmaskなんて関数があったんですね。知りませんでした。これでほぼ動作が全て解明されました。
Python3
1 np.putmask(values, mask, fill_value)
ところでskipnaがデフォルトでTrueなのでFalseにすればNaNが返るらしいことが分かりましたので。試してみた結果
Python3
1print(a.sum(skipna=False)) 2 3A NaN 4B 5.0 5C NaN 6dtype: float64
以上ご参考まで。
投稿2020/04/27 00:16
編集2020/04/27 00:59退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
DataFrame.sum(self, axis=None, skipna=None, level=None, numeric_only=None, min_count=0, **kwargs)[source]
Return the sum of the values for the requested axis.
This is equivalent to the method numpy.sum.
Parameters
axis{index (0), columns (1)}
Axis for the function to be applied on.
skipnabool, default True
Exclude NA/null values when computing the result.
levelint or level name, default None
If the axis is a MultiIndex (hierarchical), count along a particular level, collapsing into a Series.
numeric_onlybool, default None
Include only float, int, boolean columns. If None, will attempt to use everything, then use only numeric data. Not implemented for Series.
min_countint, default 0
The required number of valid values to perform the operation. If fewer than min_count non-NA values are present the result will be NA.
New in version 0.22.0: Added with the default being 0. This means the sum of an all-NA or empty Series is 0, and the product of an all-NA or empty Series is 1.
**kwargs
Additional keyword arguments to be passed to the function.
投稿2020/04/26 15:11
総合スコア83
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/04/26 17:29