バージョン 0.22.0 (2017年12月29日)#

これは0.21.1からのメジャーリリースで、APIを破壊する変更が1つ含まれています。すべてのユーザーは、リリースノート(単数形!)を注意深く読んだ上で、このバージョンにアップグレードすることをお勧めします。

下位互換性のない API の変更#

pandas 0.22.0 では、空またはすべての NA の合計と積の処理方法が変更されました。概要は以下の通りです。

  • 空またはすべての NASeries の合計は、現在 0 です。

  • 空またはすべての NASeries の積は、現在 1 です。

  • 結果が有効であるために必要な有効な値の最小数を制御する min_count パラメータを .sum().prod() に追加しました。min_count 未満の非 NA 値が存在する場合、結果は NA になります。デフォルトは 0 です。NaN を返すには、0.21 の動作として min_count=1 を使用します。

背景: pandas 0.21では、bottleneckがインストールされているかどうかに応じて、すべてのNAシリーズの戻り値における長年の不整合を修正しました。すべてのNaNまたは空のSeries/DataFrameの合計/積は一貫してNaNになりましたを参照してください。同時に、空のSeriesの合計と積もNaNに変更しました。

フィードバックに基づいて、これらの変更を部分的に元に戻しました。

算術演算#

空またはすべての NASeries のデフォルトの合計は、現在 0 です。

pandas 0.21.x

In [1]: pd.Series([]).sum()
Out[1]: nan

In [2]: pd.Series([np.nan]).sum()
Out[2]: nan

pandas 0.22.0

In [1]: pd.Series([]).sum()
Out[1]: 0

In [2]: pd.Series([np.nan]).sum()
Out[2]: 0.0

デフォルトの動作は、bottleneck がインストールされている pandas 0.20.3 と同じです。また、空の配列やすべての NA の配列に対する NumPy の np.nansum の動作とも一致します。

空のシリーズの合計が NaN を返すようにするには (bottleneck なしの pandas 0.20.3 または pandas 0.21.x のデフォルトの動作)、min_count キーワードを使用します。

In [3]: pd.Series([]).sum(min_count=1)
Out[3]: nan

skipna パラメータのおかげで、すべての NA シリーズの .sum は、概念的には skipna=True (デフォルト) の空のシリーズの .sum と同じです。

In [4]: pd.Series([np.nan]).sum(min_count=1)  # skipna=True by default
Out[4]: nan

min_count パラメータは、非 NA の合計または積に必要となる 非ヌル 値の最小数を指します。

Series.prod()Series.sum() と同様に動作するように更新され、代わりに 1 を返します。

In [5]: pd.Series([]).prod()
Out[5]: 1

In [6]: pd.Series([np.nan]).prod()
Out[6]: 1.0

In [7]: pd.Series([]).prod(min_count=1)
Out[7]: nan

これらの変更は、DataFrame.sum()DataFrame.prod() にも影響します。最後に、pandas のいくつかのあまり明白でない場所もこの変更の影響を受けます。

カテゴリカルによるグループ化#

Categorical でグループ化し、合計を計算すると、観測値のないカテゴリでは NaN の代わりに 0 が返されるようになりました。積は NaN の代わりに 1 を返すようになりました。

pandas 0.21.x

In [8]: grouper = pd.Categorical(['a', 'a'], categories=['a', 'b'])

In [9]: pd.Series([1, 2]).groupby(grouper, observed=False).sum()
Out[9]:
a    3.0
b    NaN
dtype: float64

pandas 0.22

In [8]: grouper = pd.Categorical(["a", "a"], categories=["a", "b"])

In [9]: pd.Series([1, 2]).groupby(grouper, observed=False).sum()
Out[9]: 
a    3
b    0
Length: 2, dtype: int64

観測されていないグループに対して NaN を返す 0.21 の動作を復元するには、min_count>=1 を使用します。

In [10]: pd.Series([1, 2]).groupby(grouper, observed=False).sum(min_count=1)
Out[10]: 
a    3.0
b    NaN
Length: 2, dtype: float64

リサンプリング#

すべての NA ビンの合計と積は、合計では NaN から 0 に、積では 1 に変更されました。

pandas 0.21.x

In [11]: s = pd.Series([1, 1, np.nan, np.nan],
   ....:               index=pd.date_range('2017', periods=4))
   ....: s
Out[11]:
2017-01-01    1.0
2017-01-02    1.0
2017-01-03    NaN
2017-01-04    NaN
Freq: D, dtype: float64

In [12]: s.resample('2d').sum()
Out[12]:
2017-01-01    2.0
2017-01-03    NaN
Freq: 2D, dtype: float64

pandas 0.22.0

In [11]: s = pd.Series([1, 1, np.nan, np.nan], index=pd.date_range("2017", periods=4))

In [12]: s.resample("2d").sum()
Out[12]: 
2017-01-01    2.0
2017-01-03    0.0
Freq: 2D, Length: 2, dtype: float64

NaN を返す 0.21 の動作を復元するには、min_count>=1 を使用します。

In [13]: s.resample("2d").sum(min_count=1)
Out[13]: 
2017-01-01    2.0
2017-01-03    NaN
Freq: 2D, Length: 2, dtype: float64

特に、アップサンプリングを行って合計または積を計算する場合に影響があります。これは、元のシリーズが完全に有効であったとしても、アップサンプリングによって欠損値が導入されるためです。

pandas 0.21.x

In [14]: idx = pd.DatetimeIndex(['2017-01-01', '2017-01-02'])

In [15]: pd.Series([1, 2], index=idx).resample('12H').sum()
Out[15]:
2017-01-01 00:00:00    1.0
2017-01-01 12:00:00    NaN
2017-01-02 00:00:00    2.0
Freq: 12H, dtype: float64

pandas 0.22.0

In [14]: idx = pd.DatetimeIndex(["2017-01-01", "2017-01-02"])
In [15]: pd.Series([1, 2], index=idx).resample("12H").sum()
Out[15]:
2017-01-01 00:00:00    1
2017-01-01 12:00:00    0
2017-01-02 00:00:00    2
Freq: 12H, Length: 3, dtype: int64

繰り返しますが、0.21 の動作を復元するには min_count キーワードが利用できます。

In [16]: pd.Series([1, 2], index=idx).resample("12H").sum(min_count=1)
Out[16]:
2017-01-01 00:00:00    1.0
2017-01-01 12:00:00    NaN
2017-01-02 00:00:00    2.0
Freq: 12H, Length: 3, dtype: float64

ローリングと拡張#

ローリングと拡張には、すでに min_count と同様に動作する min_periods キーワードがあります。変更される唯一のケースは、min_periods=0 でローリングまたは拡張合計を行う場合です。以前は、ウィンドウに min_periods 未満の非 NA 値がある場合、NaN が返されていました。現在は 0 が返されます。

pandas 0.21.1

In [17]: s = pd.Series([np.nan, np.nan])

In [18]: s.rolling(2, min_periods=0).sum()
Out[18]:
0   NaN
1   NaN
dtype: float64

pandas 0.22.0

In [14]: s = pd.Series([np.nan, np.nan])

In [15]: s.rolling(2, min_periods=0).sum()
Out[15]: 
0    0.0
1    0.0
Length: 2, dtype: float64

min_periods=None のデフォルトの動作は変更されていません。これは min_periods がウィンドウサイズと等しいことを意味します。

互換性#

pandas の複数のバージョンで動作するライブラリを保守している場合、要件から pandas 0.21 を除外するのが最も簡単かもしれません。そうでなければ、すべての sum() 呼び出しで、合計する前に Series が空かどうかを確認する必要があります。

setuptools を使用する場合は、setup.py で以下を使用します。

install_requires=['pandas!=0.21.*', ...]

conda を使用する場合は、以下を使用します。

requirements:
  run:
    - pandas !=0.21.0,!=0.21.1

すべての NA シリーズの戻り値の不整合は、pandas 0.20.3 以前のバージョンではまだ存在することに注意してください。pandas 0.21 を避けることは、空の場合にのみ役立ちます。

貢献者#

このリリースには合計で 1 人の貢献者がパッチを提供しました。名前の横に「+」が付いている人は、初めてパッチを提供した人です。

  • Tom Augspurger