0.25.0 (2019年7月18日) の新機能#

警告

0.25.x シリーズのリリース以降、pandas は Python 3.5.3 以降のみをサポートしています。詳細については、Dropping Python 2.7 を参照してください。

警告

最小サポートされる Python バージョンは、今後のリリースで 3.6 に引き上げられる予定です。

警告

Panel は完全に削除されました。N-D ラベル付きデータ構造には、xarray を使用してください。

警告

read_pickle()read_msgpack() は、pandas バージョン 0.20.3 (GH 27082) までの後方互換性が保証されています。

これらは pandas 0.25.0 の変更点です。pandas の他のバージョンを含む完全な変更ログについては、リリースノートを参照してください。

機能強化#

リラベル付き GroupBy 集計#

pandas は、特定の列に複数の集計関数を適用する際に、出力列に名前を付けるための「名前付き集計」と呼ばれる特別な groupby 動作を追加しました (GH 18366, GH 26512)。

In [1]: animals = pd.DataFrame({'kind': ['cat', 'dog', 'cat', 'dog'],
   ...:                         'height': [9.1, 6.0, 9.5, 34.0],
   ...:                         'weight': [7.9, 7.5, 9.9, 198.0]})
   ...: 

In [2]: animals
Out[2]: 
  kind  height  weight
0  cat     9.1     7.9
1  dog     6.0     7.5
2  cat     9.5     9.9
3  dog    34.0   198.0

[4 rows x 3 columns]

In [3]: animals.groupby("kind").agg(
   ...:     min_height=pd.NamedAgg(column='height', aggfunc='min'),
   ...:     max_height=pd.NamedAgg(column='height', aggfunc='max'),
   ...:     average_weight=pd.NamedAgg(column='weight', aggfunc="mean"),
   ...: )
   ...: 
Out[3]: 
      min_height  max_height  average_weight
kind                                        
cat          9.1         9.5            8.90
dog          6.0        34.0          102.75

[2 rows x 3 columns]

.agg**kwargs として目的の列名を渡します。**kwargs の値は、最初の要素が列選択、2番目の要素が適用する集計関数であるタプルである必要があります。pandas は、関数の引数をより明確にするために pandas.NamedAgg namedtuple を提供しますが、通常のタプルも受け入れられます。

In [4]: animals.groupby("kind").agg(
   ...:     min_height=('height', 'min'),
   ...:     max_height=('height', 'max'),
   ...:     average_weight=('weight', 'mean'),
   ...: )
   ...: 
Out[4]: 
      min_height  max_height  average_weight
kind                                        
cat          9.1         9.5            8.90
dog          6.0        34.0          102.75

[2 rows x 3 columns]

名前付き集計は、列固有の集計の出力に名前を付けるための非推奨の「辞書-の-辞書」アプローチの推奨代替手段です (名前変更時の辞書を使った groupby.agg() の非推奨化)。

同様のアプローチは、Series groupby オブジェクトにも利用できるようになりました。列選択の必要がないため、値は適用する関数のみで構いません。

In [5]: animals.groupby("kind").height.agg(
   ...:     min_height="min",
   ...:     max_height="max",
   ...: )
   ...: 
Out[5]: 
      min_height  max_height
kind                        
cat          9.1         9.5
dog          6.0        34.0

[2 rows x 2 columns]

このタイプの集計は、Series groupby 集計に辞書を渡す際の非推奨の動作に対する推奨代替手段です (名前変更時の辞書を使った groupby.agg() の非推奨化)。

詳細については、名前付き集計を参照してください。

複数のラムダ関数による GroupBy 集計#

これで、GroupBy.agg (GH 26430) のリスト形式の集計に複数のラムダ関数を提供できるようになりました。

In [6]: animals.groupby('kind').height.agg([
   ...:     lambda x: x.iloc[0], lambda x: x.iloc[-1]
   ...: ])
   ...: 
Out[6]: 
      <lambda_0>  <lambda_1>
kind                        
cat          9.1         9.5
dog          6.0        34.0

[2 rows x 2 columns]

In [7]: animals.groupby('kind').agg([
   ...:     lambda x: x.iloc[0] - x.iloc[1],
   ...:     lambda x: x.iloc[0] + x.iloc[1]
   ...: ])
   ...: 
Out[7]: 
         height                weight           
     <lambda_0> <lambda_1> <lambda_0> <lambda_1>
kind                                            
cat        -0.4       18.6       -2.0       17.8
dog       -28.0       40.0     -190.5      205.5

[2 rows x 4 columns]

以前は、これらは SpecificationError を発生させていました。

MultiIndex のより良い repr#

MultiIndex インスタンスの出力は、各行のタプルを表示し、タプル項目が垂直に揃うようにすることで、MultiIndex の構造をより理解しやすくなりました。(GH 13480)

repr は次のようになります。

In [8]: pd.MultiIndex.from_product([['a', 'abc'], range(500)])
Out[8]: 
MultiIndex([(  'a',   0),
            (  'a',   1),
            (  'a',   2),
            (  'a',   3),
            (  'a',   4),
            (  'a',   5),
            (  'a',   6),
            (  'a',   7),
            (  'a',   8),
            (  'a',   9),
            ...
            ('abc', 490),
            ('abc', 491),
            ('abc', 492),
            ('abc', 493),
            ('abc', 494),
            ('abc', 495),
            ('abc', 496),
            ('abc', 497),
            ('abc', 498),
            ('abc', 499)],
           length=1000)

以前は、MultiIndex を出力すると、MultiIndex のすべての levelscodes が出力され、視覚的に魅力的ではなく、出力がわかりにくくなっていました。たとえば (範囲を 5 に制限した場合)

In [1]: pd.MultiIndex.from_product([['a', 'abc'], range(5)])
Out[1]: MultiIndex(levels=[['a', 'abc'], [0, 1, 2, 3]],
   ...:            codes=[[0, 0, 0, 0, 1, 1, 1, 1], [0, 1, 2, 3, 0, 1, 2, 3]])

新しい repr では、行数が options.display.max_seq_items (デフォルト: 100 項目) より小さい場合、すべての値が表示されます。水平方向には、options.display.width (デフォルト: 80 文字) より幅が広い場合、出力は切り捨てられます。

Series および DataFrame の切り捨てられた repr の短縮#

現在、pandas のデフォルトの表示オプションにより、Series または DataFrame の行数が 60 行を超える場合、repr はこの最大 60 行に切り捨てられます (display.max_rows オプション)。ただし、これは依然として画面の垂直方向の大部分を占める repr を生成します。したがって、新しいオプション display.min_rows が導入され、デフォルト値は 10 で、切り捨てられた repr に表示される行数を決定します。

  • 小さな Series または DataFrame の場合、最大 max_rows 行が表示されます (デフォルト: 60)。

  • max_rows を超える長さの大きな Series または DataFrame の場合、min_rows 行のみが表示されます (デフォルト: 10、つまり最初の 5 行と最後の 5 行)。

このデュアルオプションにより、比較的小さなオブジェクトの全内容を表示しつつ (例: df.head(20) はすべての 20 行を表示)、大きなオブジェクトには簡潔な repr を提供できます。

以前の単一閾値の動作に戻すには、pd.options.display.min_rows = None を設定します。

max_level パラメータをサポートする JSON 正規化#

json_normalize() は、提供された入力 dict をすべてのネストされたレベルに正規化します。新しい max_level パラメータは、正規化を終了するレベルをより詳細に制御できます (GH 23843)。

repr は次のようになります。

from pandas.io.json import json_normalize
data = [{
    'CreatedBy': {'Name': 'User001'},
    'Lookup': {'TextField': 'Some text',
               'UserField': {'Id': 'ID001', 'Name': 'Name001'}},
    'Image': {'a': 'b'}
}]
json_normalize(data, max_level=1)

リストのような値を複数行に分割する Series.explode#

SeriesDataFrame は、リストのような値を個別の行に変換する DataFrame.explode() メソッドを獲得しました。詳細については、ドキュメントのリストのような列の展開セクションを参照してください (GH 16538, GH 10511)。

典型的な使用例を以下に示します。列にコンマ区切りの文字列があります。

In [9]: df = pd.DataFrame([{'var1': 'a,b,c', 'var2': 1},
   ...:                    {'var1': 'd,e,f', 'var2': 2}])
   ...: 

In [10]: df
Out[10]: 
    var1  var2
0  a,b,c     1
1  d,e,f     2

[2 rows x 2 columns]

連鎖操作を使用すると、長い形式の DataFrame を簡単に作成できます。

In [11]: df.assign(var1=df.var1.str.split(',')).explode('var1')
Out[11]: 
  var1  var2
0    a     1
0    b     1
0    c     1
1    d     2
1    e     2
1    f     2

[6 rows x 2 columns]

その他の機能強化#

  • DataFrame.plot() のキーワード logylogx、および loglog は、シンログスケールに 'sym' 値を受け入れるようになりました。(GH 24867)

  • to_datetime() を使用して日時を解析する際に、ISO 週年形式 ('%G-%V-%u') のサポートが追加されました (GH 16607)。

  • DataFrame および Series のインデックス付けは、ゼロディム np.ndarray を受け入れるようになりました (GH 24919)。

  • Timestamp.replace() は、DST 遷移時間を明確にするための fold 引数をサポートするようになりました (GH 25017)。

  • DataFrame.at_time()Series.at_time() は、タイムゾーンを持つ datetime.time オブジェクトをサポートするようになりました (GH 24043)。

  • DataFrame.pivot_table() は、カテゴリカルデータのグループ化を高速化するために、基になる DataFrame.groupby() の呼び出しに渡される observed パラメータを受け入れるようになりました。(GH 24923)

  • Series.str は、文字列に存在するすべての大文字小文字の区別を削除する Series.str.casefold() メソッドを獲得しました (GH 25405)。

  • DataFrame.set_index() は、abc.Iterator のインスタンスに対しても、その出力が呼び出し元フレームと同じ長さである限り、動作するようになりました (GH 22484, GH 24984)。

  • DatetimeIndex.union() は、sort 引数をサポートするようになりました。sort パラメータの動作は、Index.union() の動作と一致します (GH 24994)。

  • RangeIndex.union() は、sort 引数をサポートするようになりました。sort=False の場合、常にソートされていない Int64Index が返されます。sort=None がデフォルトであり、可能な場合は単調増加の RangeIndex を返し、そうでない場合はソートされた Int64Index を返します (GH 24471)。

  • TimedeltaIndex.intersection()sort キーワードをサポートするようになりました (GH 24471)。

  • DataFrame.rename() は、存在しないキーの名前変更を試みた際にエラーを発生させる errors 引数をサポートするようになりました (GH 13473)。

  • 値が疎である DataFrame を扱うための Sparse アクセサーが追加されました (GH 25681)。

  • RangeIndex は、startstop、および step 属性を獲得しました (GH 25710)。

  • datetime.timezone オブジェクトは、タイムゾーンメソッドとコンストラクタの引数としてサポートされるようになりました (GH 25065)。

  • DataFrame.query()DataFrame.eval() は、スペースを含む名前を参照するために、バッククォートで列名を引用符で囲むことをサポートするようになりました (GH 6508)。

  • merge_asof() は、マージキーが等しくないカテゴリカルである場合に、より明確なエラーメッセージを出すようになりました (GH 26136)。

  • Rolling() は指数 (またはポアソン) ウィンドウタイプをサポートします (GH 21303)。

  • 不足している必要なインポートのエラーメッセージに、元のインポートエラーのテキストが含まれるようになりました (GH 23868)。

  • DatetimeIndexTimedeltaIndexmean メソッドを持つようになりました (GH 24757)。

  • DataFrame.describe() は、整数パーセンタイルを小数点なしでフォーマットするようになりました (GH 26660)。

  • read_spss() を使用した SPSS .sav ファイルの読み込みのサポートが追加されました (GH 26537)。

  • 既存の matplotlib 以外のプロットバックエンドを選択できるように、新しいオプション plotting.backend が追加されました。<backend-module> が pandas プロット API を実装するライブラリである pandas.set_option('plotting.backend', '<backend-module>') を使用します (GH 14130)。

  • pandas.offsets.BusinessHour は複数の営業時間間隔をサポートします (GH 15481)。

  • read_excel() は、engine='openpyxl' 引数を使用して Excel ファイルを openpyxl で読み込むことができるようになりました。これは今後のリリースでデフォルトになります (GH 11499)。

  • pandas.io.excel.read_excel() は OpenDocument テーブルの読み込みをサポートします。engine='odf' を指定して有効にします。詳細については、IO ユーザーガイドを参照してください (GH 9070)。

  • IntervalIntervalIndex、および IntervalArray は、与えられた間隔が空かどうかを示す is_empty 属性を獲得しました (GH 27219)。

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

UTC オフセット付き日付文字列によるインデックス付け#

UTC オフセット付き日付文字列を持つ DatetimeIndex を持つ DataFrame または Series をインデックス付けすると、以前は UTC オフセットが無視されていました。現在、インデックス付けでは UTC オフセットが尊重されます。(GH 24076, GH 16785)

In [12]: df = pd.DataFrame([0], index=pd.DatetimeIndex(['2019-01-01'], tz='US/Pacific'))

In [13]: df
Out[13]: 
                           0
2019-01-01 00:00:00-08:00  0

[1 rows x 1 columns]

以前の動作:

In [3]: df['2019-01-01 00:00:00+04:00':'2019-01-01 01:00:00+04:00']
Out[3]:
                           0
2019-01-01 00:00:00-08:00  0

新しい動作:

In [14]: df['2019-01-01 12:00:00+04:00':'2019-01-01 13:00:00+04:00']
Out[14]: 
                           0
2019-01-01 00:00:00-08:00  0

[1 rows x 1 columns]

レベルとコードから構築された MultiIndex#

以前は、NaN レベルまたはコード値が -1 未満の MultiIndex の構築が許可されていました。現在、コード値が -1 未満での構築は許可されず、NaN レベルに対応するコードは -1 として再割り当てされます。(GH 19387)

以前の動作:

In [1]: pd.MultiIndex(levels=[[np.nan, None, pd.NaT, 128, 2]],
   ...:               codes=[[0, -1, 1, 2, 3, 4]])
   ...:
Out[1]: MultiIndex(levels=[[nan, None, NaT, 128, 2]],
                   codes=[[0, -1, 1, 2, 3, 4]])

In [2]: pd.MultiIndex(levels=[[1, 2]], codes=[[0, -2]])
Out[2]: MultiIndex(levels=[[1, 2]],
                   codes=[[0, -2]])

新しい動作:

In [15]: pd.MultiIndex(levels=[[np.nan, None, pd.NaT, 128, 2]],
   ....:               codes=[[0, -1, 1, 2, 3, 4]])
   ....: 
Out[15]: 
MultiIndex([(nan,),
            (nan,),
            (nan,),
            (nan,),
            (128,),
            (  2,)],
           )

In [16]: pd.MultiIndex(levels=[[1, 2]], codes=[[0, -2]])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[16], line 1
----> 1 pd.MultiIndex(levels=[[1, 2]], codes=[[0, -2]])

File ~/work/pandas/pandas/pandas/core/indexes/multi.py:365, in MultiIndex.__new__(cls, levels, codes, sortorder, names, dtype, copy, name, verify_integrity)
    362     result.sortorder = sortorder
    364 if verify_integrity:
--> 365     new_codes = result._verify_integrity()
    366     result._codes = new_codes
    368 result._reset_identity()

File ~/work/pandas/pandas/pandas/core/indexes/multi.py:452, in MultiIndex._verify_integrity(self, codes, levels, levels_to_verify)
    446     raise ValueError(
    447         f"On level {i}, code max ({level_codes.max()}) >= length of "
    448         f"level ({len(level)}). NOTE: this index is in an "
    449         "inconsistent state"
    450     )
    451 if len(level_codes) and level_codes.min() < -1:
--> 452     raise ValueError(f"On level {i}, code value ({level_codes.min()}) < -1")
    453 if not level.is_unique:
    454     raise ValueError(
    455         f"Level values must be unique: {list(level)} on level {i}"
    456     )

ValueError: On level 0, code value (-2) < -1

DataFrame 上の GroupBy.apply は最初のグループを1回だけ評価する#

DataFrameGroupBy.apply() の実装は、以前は高速コードパスを使用しても安全かどうかを推測するために、指定された関数を最初のグループで一貫して2回評価していました。特に副作用のある関数の場合、これは望ましくない動作であり、予期せぬ結果につながる可能性がありました。(GH 2936, GH 2656, GH 7739, GH 10519, GH 12155, GH 20084, GH 21417)

現在、すべてのグループは1回だけ評価されます。

In [17]: df = pd.DataFrame({"a": ["x", "y"], "b": [1, 2]})

In [18]: df
Out[18]: 
   a  b
0  x  1
1  y  2

[2 rows x 2 columns]

In [19]: def func(group):
   ....:     print(group.name)
   ....:     return group
   ....: 

以前の動作:

In [3]: df.groupby('a').apply(func)
x
x
y
Out[3]:
   a  b
0  x  1
1  y  2

新しい動作:

In [3]: df.groupby('a').apply(func)
x
y
Out[3]:
   a  b
0  x  1
1  y  2

スパース値の連結#

値が疎である DataFrame が渡された場合、concat() は、SparseDataFrame ではなく、スパース値を持つ Series または DataFrame を返すようになりました (GH 25702)。

In [20]: df = pd.DataFrame({"A": pd.arrays.SparseArray([0, 1])})

以前の動作:

In [2]: type(pd.concat([df, df]))
pandas.core.sparse.frame.SparseDataFrame

新しい動作:

In [21]: type(pd.concat([df, df]))
Out[21]: pandas.core.frame.DataFrame

これは、スパース値を持つ Series に対する concat の既存の動作と一致するようになりました。concat() は、すべての値が SparseDataFrame のインスタンスである場合、引き続き SparseDataFrame を返します。

この変更は、内部で concat() を使用するルーチンにも影響します。get_dummies() などは、すべてのケースで DataFrame を返すようになりました (以前は、すべての列がダミーエンコードされている場合は SparseDataFrame が返され、そうでない場合は DataFrame が返されていました)。

concat()SparseSeries または SparseDataFrame を提供すると、以前と同様に SparseSeries または SparseDataFrame が返されます。

.str-アクセサーはより厳密な型チェックを実行する#

よりきめ細かい dtype が不足しているため、Series.str はこれまでデータが object dtype であるかどうかのみをチェックしていました。Series.str は、Series の dtype データを推測するようになりました。特に、'bytes' のみのデータは例外を発生させます (Series.str.decode()Series.str.get()Series.str.len()Series.str.slice() を除く)。GH 23163GH 23011GH 23551 を参照してください。

以前の動作:

In [1]: s = pd.Series(np.array(['a', 'ba', 'cba'], 'S'), dtype=object)

In [2]: s
Out[2]:
0      b'a'
1     b'ba'
2    b'cba'
dtype: object

In [3]: s.str.startswith(b'a')
Out[3]:
0     True
1    False
2    False
dtype: bool

新しい動作:

In [22]: s = pd.Series(np.array(['a', 'ba', 'cba'], 'S'), dtype=object)

In [23]: s
Out[23]: 
0      b'a'
1     b'ba'
2    b'cba'
Length: 3, dtype: object

In [24]: s.str.startswith(b'a')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[24], line 1
----> 1 s.str.startswith(b'a')

File ~/work/pandas/pandas/pandas/core/strings/accessor.py:139, in forbid_nonstring_types.<locals>._forbid_nonstring_types.<locals>.wrapper(self, *args, **kwargs)
    134 if self._inferred_dtype not in allowed_types:
    135     msg = (
    136         f"Cannot use .str.{func_name} with values of "
    137         f"inferred dtype '{self._inferred_dtype}'."
    138     )
--> 139     raise TypeError(msg)
    140 return func(self, *args, **kwargs)

TypeError: Cannot use .str.startswith with values of inferred dtype 'bytes'.

GroupBy 中にカテゴリカル dtype が保持される#

以前は、カテゴリカルではあるが groupby キーではない列は、groupby 操作中に object dtype に変換されていました。pandas はこれらの dtype を保持するようになりました。(GH 18502)

In [25]: cat = pd.Categorical(["foo", "bar", "bar", "qux"], ordered=True)

In [26]: df = pd.DataFrame({'payload': [-1, -2, -1, -2], 'col': cat})

In [27]: df
Out[27]: 
   payload  col
0       -1  foo
1       -2  bar
2       -1  bar
3       -2  qux

[4 rows x 2 columns]

In [28]: df.dtypes
Out[28]: 
payload       int64
col        category
Length: 2, dtype: object

以前の動作:

In [5]: df.groupby('payload').first().col.dtype
Out[5]: dtype('O')

新しい動作:

In [29]: df.groupby('payload').first().col.dtype
Out[29]: CategoricalDtype(categories=['bar', 'foo', 'qux'], ordered=True, categories_dtype=object)

非互換なインデックス型ユニオン#

互換性のない dtype のオブジェクト間で Index.union() 操作を実行すると、結果は dtype object の基本 Index になります。この動作は、以前は禁止されていた Index オブジェクト間のユニオンにも当てはまります。空の Index オブジェクトの dtype は、単に他の Index オブジェクトを返すのではなく、ユニオン操作を実行する前に評価されるようになりました。Index.union() は、A.union(B) == B.union(A) のように可換であると見なせるようになりました (GH 23525)。

以前の動作:

In [1]: pd.period_range('19910905', periods=2).union(pd.Int64Index([1, 2, 3]))
...
ValueError: can only call with other PeriodIndex-ed objects

In [2]: pd.Index([], dtype=object).union(pd.Index([1, 2, 3]))
Out[2]: Int64Index([1, 2, 3], dtype='int64')

新しい動作:

In [3]: pd.period_range('19910905', periods=2).union(pd.Int64Index([1, 2, 3]))
Out[3]: Index([1991-09-05, 1991-09-06, 1, 2, 3], dtype='object')
In [4]: pd.Index([], dtype=object).union(pd.Index([1, 2, 3]))
Out[4]: Index([1, 2, 3], dtype='object')

整数型および浮動小数点型インデックスは「互換性がある」と見なされることに注意してください。整数値は浮動小数点に強制され、精度が失われる可能性があります。詳細については、Index オブジェクトに対する集合演算を参照してください。

DataFrame GroupBy ffill/bfill はグループラベルを返さなくなった#

DataFrameGroupByffillbfillpad、および backfill メソッドは、以前は返り値にグループラベルを含んでいましたが、これは他の groupby 変換と一貫性がありませんでした。現在、埋められた値のみが返されます。(GH 21521)

In [30]: df = pd.DataFrame({"a": ["x", "y"], "b": [1, 2]})

In [31]: df
Out[31]: 
   a  b
0  x  1
1  y  2

[2 rows x 2 columns]

以前の動作:

In [3]: df.groupby("a").ffill()
Out[3]:
   a  b
0  x  1
1  y  2

新しい動作:

In [32]: df.groupby("a").ffill()
Out[32]: 
   b
0  1
1  2

[2 rows x 1 columns]

空のカテゴリカル/オブジェクト列に対する DataFrame の describe は top と freq を返すようになる#

空のカテゴリカル/オブジェクト列を持つ DataFrame.describe() を呼び出した場合、以前は 'top' と 'freq' 列が省略されていましたが、これは空でない列の出力と一貫性がありませんでした。現在、'top' と 'freq' 列は常に含まれ、空の DataFrame の場合は numpy.nan が含まれます (GH 26397)。

In [33]: df = pd.DataFrame({"empty_col": pd.Categorical([])})

In [34]: df
Out[34]: 
Empty DataFrame
Columns: [empty_col]
Index: []

[0 rows x 1 columns]

以前の動作:

In [3]: df.describe()
Out[3]:
        empty_col
count           0
unique          0

新しい動作:

In [35]: df.describe()
Out[35]: 
       empty_col
count          0
unique         0
top          NaN
freq         NaN

[4 rows x 1 columns]

__str__ メソッドは __repr__ を呼び出すようになった (以前の逆ではない)#

pandas はこれまで、pandas オブジェクトの文字列表現を主に __str__/__unicode__/__bytes__ メソッドで定義し、特定の __repr__ メソッドが見つからない場合は __repr__ メソッドから __str__ を呼び出していました。これは Python3 では不要です。pandas 0.25 では、pandas オブジェクトの文字列表現は一般的に __repr__ で定義されるようになり、特定の __str__ メソッドが存在しない場合、__str__ への呼び出しは一般的に __repr__ に渡されるようになりました (Python の標準に従う)。この変更は pandas の直接使用に対しては後方互換性がありますが、pandas オブジェクトをサブクラス化し、サブクラスに特定の __str__/__repr__ メソッドを与えている場合、__str__/__repr__ メソッドを調整する必要があるかもしれません (GH 26495)。

Interval オブジェクトによる IntervalIndex のインデックス付け#

IntervalIndex のインデックス付けメソッドは、Interval クエリに対してのみ厳密な一致を要求するように変更されました。IntervalIndex メソッドは以前、重複する Interval に一致していました。スカラーポイント (例: 整数でのクエリ) の動作は変更されていません (GH 16316)。

In [36]: ii = pd.IntervalIndex.from_tuples([(0, 4), (1, 5), (5, 8)])

In [37]: ii
Out[37]: IntervalIndex([(0, 4], (1, 5], (5, 8]], dtype='interval[int64, right]')

in 演算子 (__contains__) は、IntervalIndex 内の Intervals に対する厳密な一致の場合にのみ True を返すようになりました。以前は、IntervalIndex 内の Interval と重複する任意の Interval に対して True を返していました。

以前の動作:

In [4]: pd.Interval(1, 2, closed='neither') in ii
Out[4]: True

In [5]: pd.Interval(-10, 10, closed='both') in ii
Out[5]: True

新しい動作:

In [38]: pd.Interval(1, 2, closed='neither') in ii
Out[38]: False

In [39]: pd.Interval(-10, 10, closed='both') in ii
Out[39]: False

get_loc() メソッドは、以前の重複一致の場所を返す動作とは異なり、Interval クエリに対する厳密な一致の場所のみを返すようになりました。厳密な一致が見つからない場合は KeyError が発生します。

以前の動作:

In [6]: ii.get_loc(pd.Interval(1, 5))
Out[6]: array([0, 1])

In [7]: ii.get_loc(pd.Interval(2, 6))
Out[7]: array([0, 1, 2])

新しい動作:

In [6]: ii.get_loc(pd.Interval(1, 5))
Out[6]: 1

In [7]: ii.get_loc(pd.Interval(2, 6))
---------------------------------------------------------------------------
KeyError: Interval(2, 6, closed='right')

同様に、get_indexer() および get_indexer_non_unique() も、Interval クエリに対する厳密な一致の場所のみを返し、厳密な一致が見つからない場合は -1 を示します。

これらのインデックス付けの変更は、IntervalIndex インデックスを持つ Series または DataFrame のクエリにも適用されます。

In [40]: s = pd.Series(list('abc'), index=ii)

In [41]: s
Out[41]: 
(0, 4]    a
(1, 5]    b
(5, 8]    c
Length: 3, dtype: object

[] (__getitem__) または loc を使用して Series または DataFrame から選択する場合、Interval クエリに対する厳密な一致のみを返すようになりました。

以前の動作:

In [8]: s[pd.Interval(1, 5)]
Out[8]:
(0, 4]    a
(1, 5]    b
dtype: object

In [9]: s.loc[pd.Interval(1, 5)]
Out[9]:
(0, 4]    a
(1, 5]    b
dtype: object

新しい動作:

In [42]: s[pd.Interval(1, 5)]
Out[42]: 'b'

In [43]: s.loc[pd.Interval(1, 5)]
Out[43]: 'b'

同様に、厳密な一致ではない場合に KeyError が発生し、重複する一致は返されません。

以前の動作:

In [9]: s[pd.Interval(2, 3)]
Out[9]:
(0, 4]    a
(1, 5]    b
dtype: object

In [10]: s.loc[pd.Interval(2, 3)]
Out[10]:
(0, 4]    a
(1, 5]    b
dtype: object

新しい動作:

In [6]: s[pd.Interval(2, 3)]
---------------------------------------------------------------------------
KeyError: Interval(2, 3, closed='right')

In [7]: s.loc[pd.Interval(2, 3)]
---------------------------------------------------------------------------
KeyError: Interval(2, 3, closed='right')

overlaps() メソッドを使用すると、以前の重複する一致を返す動作を再現するブールインデクサーを作成できます。

新しい動作:

In [44]: idxr = s.index.overlaps(pd.Interval(2, 3))

In [45]: idxr
Out[45]: array([ True,  True, False])

In [46]: s[idxr]
Out[46]: 
(0, 4]    a
(1, 5]    b
Length: 2, dtype: object

In [47]: s.loc[idxr]
Out[47]: 
(0, 4]    a
(1, 5]    b
Length: 2, dtype: object

Series 上の二項 ufunc がアラインするようになった#

numpy.power() のような二項 ufunc を適用すると、両方の入力が Series の場合にアラインするようになりました (GH 23293)。

In [48]: s1 = pd.Series([1, 2, 3], index=['a', 'b', 'c'])

In [49]: s2 = pd.Series([3, 4, 5], index=['d', 'c', 'b'])

In [50]: s1
Out[50]: 
a    1
b    2
c    3
Length: 3, dtype: int64

In [51]: s2
Out[51]: 
d    3
c    4
b    5
Length: 3, dtype: int64

以前の動作

In [5]: np.power(s1, s2)
Out[5]:
a      1
b     16
c    243
dtype: int64

新しい動作

In [52]: np.power(s1, s2)
Out[52]: 
a     1.0
b    32.0
c    81.0
d     NaN
Length: 4, dtype: float64

これは、Series.add() のような pandas の他の二項演算の動作と一致します。以前の動作を維持するには、ufunc を適用する前に、もう一方の Series を配列に変換します。

In [53]: np.power(s1, s2.array)
Out[53]: 
a      1
b     16
c    243
Length: 3, dtype: int64

Categorical.argsort は欠損値を末尾に配置するようになった#

Categorical.argsort() は、欠損値を配列の末尾に配置するようになり、NumPy および pandas の他の部分と一貫性を持つようになりました (GH 21801)。

In [54]: cat = pd.Categorical(['b', None, 'a'], categories=['a', 'b'], ordered=True)

以前の動作

In [2]: cat = pd.Categorical(['b', None, 'a'], categories=['a', 'b'], ordered=True)

In [3]: cat.argsort()
Out[3]: array([1, 2, 0])

In [4]: cat[cat.argsort()]
Out[4]:
[NaN, a, b]
categories (2, object): [a < b]

新しい動作

In [55]: cat.argsort()
Out[55]: array([2, 0, 1])

In [56]: cat[cat.argsort()]
Out[56]: 
['a', 'b', NaN]
Categories (2, object): ['a' < 'b']

辞書のリストを DataFrame に渡すと列の順序が保持される#

Python 3.7 以降、dict のキーの順序は保証されています。実際には、これは Python 3.6 以降当てはまります。DataFrame コンストラクタは、辞書のリストを OrderedDict のリストと同じように扱うようになりました。つまり、辞書の順序を保持します。この変更は、pandas が Python >= 3.6 で実行されている場合にのみ適用されます (GH 27309)。

In [57]: data = [
   ....:     {'name': 'Joe', 'state': 'NY', 'age': 18},
   ....:     {'name': 'Jane', 'state': 'KY', 'age': 19, 'hobby': 'Minecraft'},
   ....:     {'name': 'Jean', 'state': 'OK', 'age': 20, 'finances': 'good'}
   ....: ]
   ....: 

以前の動作:

以前は列は辞書式にソートされていました。

In [1]: pd.DataFrame(data)
Out[1]:
   age finances      hobby  name state
0   18      NaN        NaN   Joe    NY
1   19      NaN  Minecraft  Jane    KY
2   20     good        NaN  Jean    OK

新しい動作:

列の順序は、すべてのレコードを上から下まで考慮した上で、dict のキーの挿入順序と一致するようになりました。その結果、生成される DataFrame の列の順序は、以前の pandas バージョンと比較して変更されました。

In [58]: pd.DataFrame(data)
Out[58]: 
   name state  age      hobby finances
0   Joe    NY   18        NaN      NaN
1  Jane    KY   19  Minecraft      NaN
2  Jean    OK   20        NaN     good

[3 rows x 5 columns]

依存関係の最小バージョン引き上げ#

Python 2.7 のサポートを中止したため、多くのオプションの依存関係が最小バージョンを更新しました (GH 25725, GH 24942, GH 25752)。独立して、一部の依存関係の最小サポートバージョンが更新されました (GH 23519, GH 25554)。インストールされている場合、次のものが必要になりました。

パッケージ

最小バージョン

必須

numpy

1.13.3

X

pytz

2015.4

X

python-dateutil

2.6.1

X

bottleneck

1.2.1

numexpr

2.6.2

pytest (開発)

4.0.2

オプションのライブラリについては、一般的に最新バージョンを使用することが推奨されます。以下の表は、pandas の開発全体で現在テストされているライブラリごとの最低バージョンを示しています。最低テストバージョンより古いオプションのライブラリは動作する可能性がありますが、サポートされているとはみなされません。

パッケージ

最小バージョン

beautifulsoup4

4.6.0

fastparquet

0.2.1

gcsfs

0.2.2

lxml

3.8.0

matplotlib

2.2.2

openpyxl

2.4.8

pyarrow

0.9.0

pymysql

0.7.1

pytables

3.4.2

scipy

0.19.0

sqlalchemy

1.1.4

xarray

0.8.2

xlrd

1.1.0

xlsxwriter

0.9.8

xlwt

1.2.0

詳細については、依存関係 および オプションの依存関係 を参照してください。

その他の API の変更#

  • DatetimeTZDtype は、pytz タイムゾーンを共通のタイムゾーンインスタンスに標準化するようになりました (GH 24713)。

  • TimestampTimedelta スカラーは、それぞれ Timestamp.to_datetime64() および Timedelta.to_timedelta64() のエイリアスとして to_numpy() メソッドを実装するようになりました。(GH 24653)

  • Timestamp.strptime()NotImplementedError を発生させるようになりました (GH 25016)。

  • サポートされていないオブジェクトとの Timestamp の比較は、TypeError を発生させる代わりに NotImplemented を返すようになりました。これは、サポートされていないリッチ比較が他のオブジェクトに委譲され、datetime オブジェクトに対する Python 3 の動作と一貫性があることを意味します (GH 24011)。

  • 入力 Indexname を保持していなかった DatetimeIndex.snap() のバグ (GH 25575)

  • DataFrameGroupBy.agg()arg 引数が func に変更されました (GH 26089)。

  • Window.aggregate()arg 引数が func に変更されました (GH 26372)。

  • ほとんどの pandas クラスには __bytes__ メソッドがあり、オブジェクトの python2 スタイルのバイト文字列表現を取得するために使用されていました。このメソッドは Python2 の廃止の一環として削除されました (GH 26447)。

  • 1レベルの MultiIndex に対して .str-アクセサーが無効になりました。必要であれば MultiIndex.to_flat_index() を使用してください (GH 23679)。

  • クリップボード用のgtkパッケージのサポートを削除しました (GH 26563)。

  • サポートされていないバージョンの Beautiful Soup 4 を使用すると、ValueError ではなく ImportError が発生するようになりました (GH 27063)。

  • Series.to_excel() および DataFrame.to_excel() は、タイムゾーン対応データを保存する際に ValueError を発生させるようになりました。(GH 27008, GH 7056)

  • ExtensionArray.argsort() は、NA 値をソートされた配列の末尾に配置します。(GH 21801)

  • DataFrame.to_hdf() および Series.to_hdf() は、fixed 形式で拡張データ型を持つ MultiIndex を保存する際に NotImplementedError を発生させるようになりました。(GH 7775)

  • read_csv() で重複した names を渡すと ValueError が発生するようになりました (GH 17346)。

非推奨#

疎なサブクラス#

SparseSeries および SparseDataFrame サブクラスは非推奨です。その機能は、疎な値を持つ Series または DataFrame でより良く提供されます。

以前の方法

df = pd.SparseDataFrame({"A": [0, 0, 1, 2]})
df.dtypes

新しい方法

In [59]: df = pd.DataFrame({"A": pd.arrays.SparseArray([0, 0, 1, 2])})

In [60]: df.dtypes
Out[60]: 
A    Sparse[int64, 0]
Length: 1, dtype: object

2つのアプローチのメモリ使用量は同じです (GH 19239)。

msgpack形式#

msgpack 形式は 0.25 で非推奨となり、将来のバージョンで削除される予定です。pandas オブジェクトのオンザワイヤ伝送には pyarrow を使用することをお勧めします。(GH 27084)

その他の非推奨事項#

  • 非推奨の .ix[] インデクサーは、DeprecationWarning の代わりに、より目立つ FutureWarning を発生させるようになりました (GH 26438)。

  • pandas.to_timedelta()pandas.Timedelta() および pandas.TimedeltaIndex()units のパラメータ units=M (月) および units=Y (年) は非推奨になりました (GH 16344)。

  • pandas.concat()join_axes キーワードを非推奨にしました。代わりに、結果または入力に対して DataFrame.reindex() または DataFrame.reindex_like() を使用してください (GH 21951)。

  • SparseArray.values 属性は非推奨です。代わりに np.asarray(...) または SparseArray.to_dense() メソッドを使用できます (GH 26421)。

  • 関数 pandas.to_datetime()pandas.to_timedelta()box キーワードを非推奨にしました。代わりに、to_numpy() または Timestamp.to_datetime64() または Timedelta.to_timedelta64() を使用できます。(GH 24416)

  • DataFrame.compound() および Series.compound() メソッドは非推奨であり、将来のバージョンで削除されます (GH 26405)。

  • RangeIndex の内部属性 _start_stop、および _step は非推奨になりました。代わりに、公開属性 startstop、および step を使用してください (GH 26581)。

  • Series.ftype()Series.ftypes()、および DataFrame.ftypes() メソッドは非推奨であり、将来のバージョンで削除されます。代わりに、Series.dtype() および DataFrame.dtypes() を使用してください (GH 26705)。

  • Series.get_values()DataFrame.get_values()Index.get_values()SparseArray.get_values()、および Categorical.get_values() メソッドは非推奨です。代わりに np.asarray(..) または to_numpy() のいずれかを使用できます (GH 19617)。

  • NumPy の ufunc の「outer」メソッド、例えば np.subtract.outer は、Series オブジェクトでは非推奨になりました。まず、Series.array を使用して入力を配列に変換してください (GH 27186)。

  • Timedelta.resolution() は非推奨となり、Timedelta.resolution_string() に置き換えられました。将来のバージョンでは、Timedelta.resolution() は標準ライブラリの datetime.timedelta.resolution と同様に動作するように変更されます (GH 21344)。

  • read_table() は非推奨ではなくなりました。(GH 25220)

  • Index.dtype_str は非推奨です。(GH 18262)

  • Series.imagSeries.real は非推奨です。(GH 18262)

  • Series.put() は非推奨です。(GH 18262)

  • Index.item()Series.item() は非推奨です。(GH 18262)

  • CategoricalDtype のデフォルト値 ordered=None は、ordered=False に置き換えられました。カテゴリカル型間で変換する際、ordered=True は、その順序を保持するために明示的に渡す必要があります。(GH 26336)

  • Index.contains() は非推奨です。代わりに key in index (__contains__) を使用してください (GH 17753)。

  • DataFrame.get_dtype_counts() は非推奨です。(GH 18262)

  • Categorical.ravel()np.ndarray の代わりに Categorical を返します (GH 27199)。

以前のバージョンの非推奨/変更の削除#

  • Panel を削除しました (GH 25047, GH 25191, GH 25231)

  • 以前非推奨であった read_excel()sheetname キーワードを削除しました (GH 16442, GH 20938)。

  • 以前非推奨だった TimeGrouper を削除しました (GH 16942)。

  • 以前に非推奨化された read_excel()parse_cols キーワードを削除しました (GH 16488)。

  • 以前非推奨だった pd.options.html.border を削除しました (GH 16970)。

  • 以前非推奨だった convert_objects を削除しました (GH 11221)。

  • DataFrame および Series の以前非推奨だった select メソッドを削除しました (GH 17633)。

  • rename_categories()Series がリストのように扱われる以前非推奨だった動作を削除しました (GH 17982)。

  • 以前非推奨だった DataFrame.reindex_axis および Series.reindex_axis を削除しました (GH 17842)。

  • Series.rename_axis() または DataFrame.rename_axis() で列またはインデックスラベルを変更する以前非推奨だった動作を削除しました (GH 17842)。

  • read_html()read_csv()、および DataFrame.to_csv() の以前非推奨だった tupleize_cols キーワード引数を削除しました (GH 17877, GH 17820)。

  • 以前非推奨だった DataFrame.from.csvSeries.from_csv を削除しました (GH 17812)。

  • DataFrame.where() および DataFrame.mask() の以前非推奨だった raise_on_error キーワード引数を削除しました (GH 17744)。

  • 以前非推奨だった astypeorderedcategories キーワード引数を削除しました (GH 17742)。

  • 以前非推奨だった cdate_range を削除しました (GH 17691)。

  • SeriesGroupBy.nth()dropna キーワード引数の以前非推奨だった True オプションを削除しました (GH 17493)。

  • Series.take()DataFrame.take() の以前非推奨だった convert キーワード引数を削除しました (GH 17352)。

  • datetime.date オブジェクトとの算術演算の以前非推奨だった動作を削除しました (GH 21152)。

パフォーマンス改善#

  • SparseArray の初期化が大幅に高速化され、v0.20.0 で導入されたパフォーマンス低下が修正されました (GH 24985)。

  • DataFrame.to_stata() は、文字列または非ネイティブエンディアンの列を持つデータを出力する際に高速化されました (GH 25045)。

  • Series.searchsorted() のパフォーマンスが向上しました。dtype が int8/int16/int32 で、検索キーが dtype の整数境界内にある場合、高速化が特に顕著です (GH 22034)。

  • GroupBy.quantile() のパフォーマンスが向上しました (GH 20405)。

  • RangeIndex でのスライシングやその他の選択された操作のパフォーマンスが向上しました (GH 26565, GH 26617, GH 26722)。

  • RangeIndex は、実際のハッシュテーブルをインスタンス化することなく標準的なルックアップを実行するようになり、メモリを節約します (GH 16685)。

  • read_csv() のパフォーマンスが、より高速なトークン化と小さな浮動小数点数のより高速な解析により向上しました (GH 25784)。

  • read_csv() のパフォーマンスが、N/A およびブール値の高速な解析により向上しました (GH 25804)。

  • IntervalIndex.is_monotonicIntervalIndex.is_monotonic_increasing、および IntervalIndex.is_monotonic_decreasing のパフォーマンスが、MultiIndex への変換を削除することで向上しました (GH 24813)。

  • DataFrame.to_csv() が datetime dtypes を書き込む際のパフォーマンスを改善しました (GH 25708)

  • read_csv() のパフォーマンスを改善しました。MM/YYYY および DD/MM/YYYY 日付形式のパースが大幅に高速化されました (GH 25922)

  • NaN を格納できない dtypes の nanops のパフォーマンスを改善しました。特に Series.all()Series.any() で高速化が顕著です (GH 25070)

  • カテゴリカルシリーズの辞書マッパーに対する Series.map() のパフォーマンスを改善しました。すべての値をマッピングする代わりにカテゴリをマッピングするようになりました (GH 23785)

  • IntervalIndex.intersection() のパフォーマンスを改善しました (GH 24813)

  • read_csv() のパフォーマンスを改善しました。整数/浮動小数点ゼロおよび浮動小数点 NaN の日付列を余分な文字列変換なしでより高速に連結し、文字列が日付である可能性のチェックをより高速化しました (GH 25754)

  • IntervalIndex.is_unique のパフォーマンスを改善しました。MultiIndex への変換を削除しました (GH 24813)

  • 特殊なコードパスを再度有効にすることで、DatetimeIndex.__iter__() のパフォーマンスを回復しました (GH 26702)

  • 少なくとも1つの CategoricalIndex レベルを持つ MultiIndex を構築する際のパフォーマンスを改善しました (GH 22044)

  • SettingWithCopyWarning のチェック時にガベージコレクションが不要になるようにパフォーマンスを改善しました (GH 27031)

  • to_datetime() の cache パラメータのデフォルト値を True に変更しました (GH 26043)

  • 非一意で単調なデータが与えられた場合の DatetimeIndex および PeriodIndex のスライス操作のパフォーマンスを改善しました (GH 27136)。

  • インデックス指向のデータに対する pd.read_json() のパフォーマンスを改善しました (GH 26773)。

  • MultiIndex.shape() のパフォーマンスを改善しました (GH 27384)。

バグ修正#

カテゴリカル#

日付時刻ライク#

  • 遠い未来の日付と format 引数が指定されて呼び出された際に、OutOfBoundsDatetime を発生させる代わりに (誤った) ValueError を発生させていた to_datetime() のバグを修正しました (GH 23830)

  • cache=True で呼び出され、arg{None, numpy.nan, pandas.NaT} のセットから少なくとも2つの異なる要素を含む場合に、InvalidIndexError: Reindexing only valid with uniquely valued Index objects を発生させていた to_datetime() のバグを修正しました (GH 22305)

  • DataFrame および Series で、dtype='datetime64[ns] のタイムゾーン対応データがナイーブ型にキャストされなかったバグを修正しました (GH 25843)

  • サブクラス化された datetime を使用する際に例外が発生するのを防ぐため、さまざまな日時関数における Timestamp の型チェックを改善しました (GH 25851)

  • Series および DataFrame の repr で、dtype=objectnp.datetime64('NaT')np.timedelta64('NaT')NaN として表現されていたバグを修正しました (GH 25445)

  • エラーが coerce に設定されている場合に、無効な引数を NaT で置き換えない to_datetime() のバグを修正しました (GH 26122)

  • ゼロ以外の月を含む DateOffsetDatetimeIndex に追加すると ValueError が発生するバグを修正しました (GH 26258)

  • format='%Y%m%d' および error='coerce' で、無効な日付と NaN 値が混在する状態で呼び出された際に、未処理の OverflowError を発生させていた to_datetime() のバグを修正しました (GH 25512)

  • 日付時刻のようなインデックス (DatetimeIndexTimedeltaIndexPeriodIndex) の isin() で、levels パラメータが無視されていたバグを修正しました (GH 26675)

  • to_datetime() で、errors='ignore' を指定し、長さが6桁以上の無効な整数日付に対して format='%Y%m%d' を使用した場合に TypeError が発生するバグを修正しました。

  • PeriodIndex をゼロ次元の numpy 配列と比較する際のバグを修正しました (GH 26689)

  • 非ns単位の numpy datetime64 配列と範囲外のタイムスタンプから Series または DataFrame を構築する際に、不正なデータが生成されるバグを修正し、今後は正しく OutOfBoundsDatetime エラーが発生するようになりました (GH 26206)。

  • 非常に大きいまたは非常に小さい日付に対して不要な OverflowError が発生していた date_range() のバグを修正しました (GH 26651)

  • Timestampnp.timedelta64 オブジェクトに追加すると、Timestamp を返す代わりに例外が発生していたバグを修正しました (GH 24775)

  • np.datetime64 オブジェクトを含むゼロ次元の numpy 配列と Timestamp を比較すると、誤って TypeError が発生していたバグを修正しました (GH 26916)

  • cache=True で呼び出され、arg が異なるオフセットを持つ datetime 文字列を含む場合に、ValueError: Tz-aware datetime.datetime cannot be converted to datetime64 unless utc=True が発生していた to_datetime() のバグを修正しました (GH 26097)

Timedelta#

  • TimedeltaIndex.intersection() で、非単調なインデックスの場合に、実際には共通部分が存在するのに空の Index が返されることがあったバグを修正しました (GH 25913)

  • TimedeltaNaT の比較で TypeError が発生していたバグを修正しました (GH 26039)

  • BusinessHourTimestamp に加算または減算する際に、結果の時刻がそれぞれ翌日または前日になったバグを修正しました (GH 26381)

  • TimedeltaIndex をゼロ次元の numpy 配列と比較する際のバグを修正しました (GH 26689)

タイムゾーン#

  • DatetimeIndex.to_frame() で、タイムゾーン対応データがタイムゾーン非対応データに変換されていたバグを修正しました (GH 25809)

  • utc=True を指定した to_datetime() で、以前にパースされた UTC オフセットが後続の引数に適用されていたバグを修正しました (GH 24992)

  • Timestamp.tz_localize() および Timestamp.tz_convert()freq が伝播しないバグを修正しました (GH 25241)

  • Series.at() で、タイムゾーン付きの Timestamp を設定すると TypeError が発生するバグを修正しました (GH 25506)

  • DataFrame.update() で、タイムゾーン対応データで更新するとタイムゾーン非対応データが返されるバグを修正しました (GH 25807)

  • 混合 UTC オフセットを持つ datetime 文字列とナイーブな Timestamp を渡した際に、情報量の少ない RuntimeError が発生していた to_datetime() のバグを修正しました (GH 25978)

  • unit='ns' を指定した to_datetime() で、パースされた引数からタイムゾーン情報が削除されていたバグを修正しました (GH 26168)

  • DataFrame.join() で、タイムゾーン対応インデックスとタイムゾーン対応列を結合すると、NaN の列が結果として返されていたバグを修正しました (GH 26335)

  • date_range() で、あいまいな、または存在しない開始時刻または終了時刻が、それぞれ ambiguous または nonexistent キーワードによって処理されなかったバグを修正しました (GH 27088)

  • タイムゾーン対応の DatetimeIndex とタイムゾーン非対応の DatetimeIndex を結合する際の DatetimeIndex.union() のバグを修正しました (GH 21671)

  • numpy の還元関数 (例: numpy.minimum()) をタイムゾーン対応の Series に適用すると発生していたバグを修正しました (GH 15552)

数値#

  • 大きな負の数が不適切に処理されていた to_numeric() のバグを修正しました (GH 24910)

  • errorscoerce でない場合でも、数値が浮動小数点に強制変換されていた to_numeric() のバグを修正しました (GH 24910)

  • errors の無効な値が許可されていた to_numeric() のバグを修正しました (GH 26466)

  • format で、浮動小数点複素数が適切な表示精度とトリミングでフォーマットされていなかったバグを修正しました (GH 25514)

  • DataFrame.corr() および Series.corr() のエラーメッセージのバグを修正しました。呼び出し可能オブジェクトを使用できる機能を追加しました (GH 25729)

  • Series.divmod() および Series.rdivmod() が、結果として Series オブジェクトのペアを返す代わりに (誤った) ValueError を発生させていたバグを修正しました (GH 25557)

  • 数値インデックスを必要とするメソッドで、非数値インデックスが interpolate() に送信された場合に、わかりやすい例外を発生させるようになりました (GH 21662)

  • eval() で、浮動小数点数をスカラ演算子と比較する際のバグを修正しました (例: x < -0.1) (GH 25928)

  • すべてのブール配列を整数拡張配列にキャストする際に失敗していたバグを修正しました (GH 25211)

  • ゼロを含む Series オブジェクトの divmod で、誤って AttributeError が発生していたバグを修正しました (GH 26987)

  • Series のフロア除算 (//) および divmod で、正の数 // ゼロが Inf ではなく NaN で埋められていた不整合を修正しました (GH 27321)

変換#

  • DataFrame.astype() で、列と型の辞書を渡した場合に errors パラメータが無視されていたバグを修正しました (GH 25905)

文字列#

  • Series.str のいくつかのメソッドの __name__ 属性が誤って設定されていたバグを修正しました (GH 23551)

  • 間違った dtype の SeriesSeries.str.cat() に渡した場合のエラーメッセージを改善しました (GH 22722)

Interval#

インデックス付け#

  • 非数値オブジェクトのリストを DataFrame.iloc() に渡した場合の例外メッセージを改善しました (GH 25753)。

  • 長さが異なるブールインデクサを .iloc または .loc に渡した場合の例外メッセージを改善しました (GH 26658)。

  • MultiIndex をインデックス付けする際に、存在しないキーが元のキーを表示していなかった KeyError 例外メッセージのバグを修正しました (GH 27250)。

  • .iloc.loc で、ブールインデクサに項目が少なすぎる場合に IndexError が発生しなかったバグを修正しました (GH 26658)。

  • DataFrame.loc() および Series.loc() で、キーが MultiIndex のレベル数以下であった場合に KeyError が発生しなかったバグを修正しました (GH 14885)。

  • DataFrame.append() が、追加するデータに新しい列が含まれる場合に、将来 KeyError がスローされることを示す誤った警告を生成していたバグを修正しました (GH 22252)。

  • DataFrame.to_csv() が、インデックスが単一レベルの MultiIndex であったリインデックスされたデータフレームに対してセグメンテーション違反を引き起こしていたバグを修正しました (GH 26303)。

  • arrays.PandasArrayDataFrame に割り当てるとエラーが発生していたバグを修正しました (GH 26390)

  • DataFrame.query() 文字列で使用される呼び出し可能なローカル参照にキーワード引数を許可しました (GH 26426)

  • MultiIndex レベルを、欠損している正確に1つのラベルを含むリストでインデックス付けした際に発生していた KeyError を修正しました (GH 27148)

  • MultiIndex での部分一致 TimestampAttributeError が発生していたバグを修正しました (GH 26944)

  • Interval 値を持つ Categorical および CategoricalIndex で、Interval の値と比較できないオブジェクトに対して in 演算子 (__contains) を使用した場合のバグを修正しました (GH 23705)

  • 単一のタイムゾーン対応 datetime64[ns] 列を持つ DataFrameDataFrame.loc() および DataFrame.iloc() で、誤って Series ではなくスカラが返されていたバグを修正しました (GH 27110)

  • CategoricalIndex および Categorical で、in 演算子 (__contains__) を使用してリストが渡された場合に、TypeError ではなく誤って ValueError が発生していたバグを修正しました (GH 21729)

  • SeriesTimedelta オブジェクトで新しい値を設定する際に、誤って値が整数にキャストされていたバグを修正しました (GH 22717)

  • Series で、タイムゾーン対応の datetime を使用して新しいキーを設定 (__setitem__) する際に、誤って ValueError が発生していたバグを修正しました (GH 12862)

  • 読み取り専用のインデクサでインデックス付けした際の DataFrame.iloc() のバグを修正しました (GH 17192)

  • Series で、タイムゾーン対応の datetime 値を持つ既存のタプルキーを設定 (__setitem__) する際に、誤って TypeError が発生していたバグを修正しました (GH 20441)

欠損値#

  • Series.interpolate() で、引数 order が必須なのに省略された場合に表示される誤解を招く例外メッセージを修正しました (GH 10633, GH 24014)。

  • DataFrame.dropna() で無効な axis パラメータが渡された場合に、例外メッセージに表示されるクラス型を修正しました (GH 25555)

  • DataFrame.fillna() で、limit が正の整数でない場合に ValueError がスローされるようになりました (GH 27042)

MultiIndex#

  • MultiIndex のメンバーシップをテストする際に、Timedelta によって誤った例外がスローされていたバグを修正しました (GH 24570)

IO#

  • DataFrame.to_html() で、値がフルコンテンツを出力する代わりに表示オプションを使用して切り捨てられていたバグを修正しました (GH 17004)

  • Windows の Python 3 で utf-16 文字をコピーする際に to_clipboard() を使用するとテキストが欠落していたバグを修正しました (GH 25040)

  • read_json()orient='table' を指定した場合に、dtypes が JSON スキーマで既に定義されているため適用できないのに、デフォルトで dtypes を推測しようとしていたバグを修正しました (GH 21345)

  • read_json()orient='table' と float インデックスを指定した場合に、インデックスの dtype が JSON スキーマで既に定義されているため適用できないのに、デフォルトでインデックスの dtype を推測していたバグを修正しました (GH 25433)

  • read_json()orient='table' と float 列名文字列を指定した場合に、列名タイプを Timestamp に変換していましたが、列名が JSON スキーマで既に定義されているため適用できないバグを修正しました (GH 25435)

  • json_normalize()errors='ignore' を指定した場合に、入力データ内の欠損値が結果の DataFramenumpy.nan ではなく文字列 "nan" で埋められていたバグを修正しました (GH 25468)

  • DataFrame.to_html() で、classes パラメータに無効な型を使用した場合に、AssertionError ではなく TypeError が発生するようになりました (GH 25608)

  • DataFrame.to_string() および DataFrame.to_latex() で、header キーワードが使用された場合に不正な出力が発生していたバグを修正しました (GH 16718)

  • Python 3.6+ の Windows で、UTF8 エンコードされたファイル名を read_csv() が正しく解釈しなかったバグを修正しました (GH 15086)

  • 欠損値を含む列を変換する際の pandas.read_stata() および pandas.io.stata.StataReader のパフォーマンスを改善しました (GH 25772)

  • DataFrame.to_html() で、ヘッダーの数値が丸め時に表示オプションを無視していたバグを修正しました (GH 17280)

  • read_hdf() で、PyTables で直接書き込まれた HDF5 ファイルからテーブルを読み取る際に、start または stop 引数を介したサブ選択を使用すると ValueError で失敗していたバグを修正しました (GH 11188)

  • read_hdf() で、KeyError が発生した後にストアが適切に閉じられなかったバグを修正しました (GH 25766)

  • Stata dta ファイルで値ラベルが繰り返された場合の失敗の説明と回避策を改善しました (GH 25772)

  • pandas.read_stata() および pandas.io.stata.StataReader を改善し、Stata によって保存された不適切にフォーマットされた 118 形式のファイルを読み取れるようにしました (GH 25960)

  • DataFrame.to_html()col_space パラメータを改善し、文字列を受け入れて CSS の長さの値を正しく設定できるようにしました (GH 25941)

  • URL に # 文字を含む S3 からオブジェクトをロードする際のバグを修正しました (GH 25945)

  • read_gbq()use_bqstorage_api パラメータを追加し、大きなデータフレームのダウンロードを高速化しました。この機能には、pandas-gbq ライブラリのバージョン 0.10.0、および google-cloud-bigquery-storagefastavro ライブラリが必要です (GH 26104)

  • 数値データを扱う際の DataFrame.to_json() のメモリリークを修正しました (GH 24889)

  • read_json() で、Z を含む日付文字列が UTC タイムゾーンに変換されなかったバグを修正しました (GH 26168)

  • read_csv()cache_dates=True パラメータを追加し、一意な日付をパース時にキャッシュできるようにしました (GH 25990)

  • DataFrame.to_excel() は、呼び出し元の寸法が Excel の制限を超えた場合に ValueError を発生させるようになりました (GH 26051)

  • pandas.read_csv() で、BOM が engine='python' を使用した不正なパースを引き起こしていたバグを修正しました (GH 26545)

  • read_excel() は、入力が pandas.io.excel.ExcelFile 型で engine パラメータが渡された場合に ValueError を発生させるようになりました。pandas.io.excel.ExcelFile にはエンジンが定義されているためです (GH 26566)

  • where='' が指定された HDFStore から選択する際のバグを修正しました (GH 26610)。

  • DataFrame.to_excel() で、結合されたセル内のカスタムオブジェクト (例: PeriodIndex) が Excel ライターにとって安全な型に変換されていなかったバグを修正しました (GH 27006)

  • read_hdf() で、タイムゾーン対応の DatetimeIndex を読み取ると TypeError が発生していたバグを修正しました (GH 11926)

  • to_msgpack() および read_msgpack() で、無効なパスに対して FileNotFoundError ではなく ValueError が発生していたバグを修正しました (GH 27160)

  • DataFrame.to_parquet() で、データフレームに列がない場合に ValueError が発生していたバグを修正しました (GH 27339)

  • read_csv() を使用する際に、PeriodDtype 列のパースを許可するようになりました (GH 26934)

プロット#

  • api.extensions.ExtensionArray を matplotlib のプロットで使用できなかったバグを修正しました (GH 25587)

  • DataFrame.plot() のエラーメッセージのバグを修正しました。非数値が DataFrame.plot() に渡された場合のエラーメッセージを改善しました (GH 25481)

  • 非数値/非日付時刻のインデックスをプロットする際の不正なティックラベル位置のバグを修正しました (GH 7612, GH 15912, GH 22334)

  • PeriodIndex 時系列のプロットが、頻度が頻度ルールコードの倍数である場合に失敗していたバグを修正しました (GH 14763)

  • datetime.timezone.utc タイムゾーンを持つ DatetimeIndex をプロットする際のバグを修正しました (GH 17173)

GroupBy/resample/rolling#

  • タイムゾーン対応インデックスの Resampler.agg() で、関数のリストを渡すと OverflowError が発生していたバグを修正しました (GH 22660)

  • DataFrameGroupBy.nunique() で、列レベルの名前が失われていたバグを修正しました (GH 23222)

  • タイムゾーン対応データに集約関数を適用する際の GroupBy.agg() のバグを修正しました (GH 23683)

  • GroupBy.first() および GroupBy.last() で、タイムゾーン情報が削除されていたバグを修正しました (GH 21603)

  • NA 値のみをグループ化する際の GroupBy.size() のバグを修正しました (GH 23050)

  • Series.groupby() で、以前は observed kwarg が無視されていたバグを修正しました (GH 24880)

  • Series.groupby() で、MultiIndex Series を使用して、シリーズの長さと同じラベルのリストで groupby を使用すると、不正なグループ化が発生していたバグを修正しました (GH 25704)

  • groupby 集約関数の出力順序が、すべての Python バージョンで一貫していることを確認しました (GH 25692)

  • 順序付き Categorical でグループ化し、observed=True を指定した場合に、結果のグループ順序が正しいことを確認しました (GH 25871, GH 25167)

  • Rolling.min() および Rolling.max() で、メモリリークが発生していたバグを修正しました (GH 25893)

  • Rolling.count() および .Expanding.count が以前は axis キーワードを無視していたバグを修正しました (GH 13503)

  • 日時列を持つ GroupBy.idxmax() および GroupBy.idxmin() が、不正な dtype を返していたバグを修正しました (GH 25444, GH 15306)

  • 欠損カテゴリを持つカテゴリカル列の GroupBy.cumsum()GroupBy.cumprod()GroupBy.cummin()、および GroupBy.cummax() が、不正な結果を返したり、セグメンテーション違反を引き起こしたりしていたバグを修正しました (GH 16771)

  • グループ化に NA 値が含まれる場合に、GroupBy.nth() が不正な結果を返していたバグを修正しました (GH 26011)

  • SeriesGroupBy.transform() で、空のグループを変換すると ValueError が発生していたバグを修正しました (GH 26208)

  • DataFrame.groupby() で、Grouper を渡した場合に、.groups アクセサを使用すると不正なグループが返されていたバグを修正しました (GH 26326)

  • GroupBy.agg() で、uint64 列に対して不正な結果が返されていたバグを修正しました (GH 26310)

  • Rolling.median() および Rolling.quantile() で、空のウィンドウで MemoryError が発生していたバグを修正しました (GH 26005)

  • Rolling.median() および Rolling.quantile() で、closed='left' および closed='neither' で不正な結果が返されていたバグを修正しました (GH 26005)

  • RollingWindow、および ExponentialMovingWindow 関数を改善し、不要な列を結果から除外し、すべての列が不要な場合にのみ DataError を発生させるようにしました (GH 12537)

  • Rolling.max() および Rolling.min() で、空の可変ウィンドウで不正な結果が返されていたバグを修正しました (GH 26005)

  • Window.aggregate() の引数としてサポートされていない重み付きウィンドウ関数が使用された場合に、わかりやすい例外を発生させるようになりました (GH 26597)

再整形#

  • pandas.merge() で、サフィックスに None が割り当てられた場合に列名をそのままにする代わりに、None の文字列が追加されていたバグを修正しました (GH 24782)。

  • merge() で、インデックス名でマージする際に、不正な番号のインデックスが生成されることがあったバグを修正しました (欠損インデックス値は NA に割り当てられるようになりました) (GH 24212, GH 25009)

  • to_records()column_dtypes パラメータに dtypes を受け入れるようになりました (GH 24895)

  • objs 引数として渡された場合に、OrderedDict (および Python 3.6 以降の dict) の順序が尊重されない concat() のバグ (GH 21510)

  • aggfunc 引数に list が含まれている場合、dropna 引数が False であっても NaN 値を持つ列が削除される pivot_table() のバグ (GH 22159)

  • 同じ freq を持つ2つの DatetimeIndex の結果の freq が削除される concat() のバグ (GH 3232)。

  • 同等の Categorical dtypes を持つマージがエラーを発生させる merge() のバグ (GH 22501)

  • イテレーターまたはジェネレーターの辞書 (例: pd.DataFrame({'A': reversed(range(3))})) で DataFrame をインスタンス化するとエラーが発生するバグ (GH 26349)。

  • range (例: pd.DataFrame(range(3))) で DataFrame をインスタンス化するとエラーが発生するバグ (GH 26342)。

  • 空ではないタプルを渡すとセグメンテーション違反が発生する DataFrame コンストラクタのバグ (GH 25691)

  • シリーズがタイムゾーンを認識する DatetimeIndex である場合に Series.apply() が失敗するバグ (GH 25959)

  • 大きいビンが整数オーバーフローのために誤ってエラーを発生させる可能性があった pandas.cut() のバグ (GH 26045)

  • マルチインデックスの DataFrame が、最初のレベルを最後にソートしてすべてのレベルでソートされたときにエラーがスローされる DataFrame.sort_index() のバグ (GH 26053)

  • Series.nlargest()TrueFalse よりも小さいと扱うバグ (GH 26154)

  • ピボットインデックスとして IntervalIndex を持つ DataFrame.pivot_table()TypeError が発生するバグ (GH 25814)

  • orient='index' の場合に DataFrame.from_dict()OrderedDict の順序を無視するバグ (GH 8425)。

  • タイムゾーンを認識する datetime 列を持つ DataFrame を転置すると、誤って ValueError が発生する DataFrame.transpose() のバグ (GH 26825)

  • values としてタイムゾーンを認識する列をピボットすると、タイムゾーン情報が削除される pivot_table() のバグ (GH 14948)

  • 複数の by 列を指定し、そのうちの1つが datetime64[ns, tz] dtype である場合に merge_asof() のバグ (GH 26649)

スパース#

  • SparseArray の初期化が大幅に高速化され、v0.20.0 で導入されたパフォーマンス低下が修正されました (GH 24985)。

  • None をデータとして渡すと default_fill_value が無視される SparseFrame コンストラクタのバグ (GH 16807)

  • 値の長さがインデックスの長さと一致しない列を追加すると、ValueError が発生する代わりに AssertionError が発生する SparseDataFrame のバグ (GH 25484)

  • Series.sparse.from_coo() で、coo 行列ではない入力に対して TypeError を返すように、より良いエラーメッセージを導入しました (GH 26554)

  • SparseArray 上の numpy.modf() のバグ。現在、SparseArray のタプルが返されます (GH 26946)。

ビルドの変更#

  • macOS での PyPy のインストールエラーを修正 (GH 26536)

ExtensionArray#

  • カスタムの na_sentinel を持つ ExtensionArray を渡した場合の factorize() のバグ (GH 25696)。

  • Series.count() が ExtensionArrays 内の NA 値を誤ってカウントする (GH 26835)

  • 拡張配列でバックアップされた Series に適用される NumPy ufuncs をより適切に処理するために Series.__array_ufunc__ を追加しました (GH 23293)。

  • キーワード引数 deepExtensionArray.copy() から削除されました (GH 27083)

その他#

  • ベンダーの UltraJSON 実装から未使用の C 関数を削除しました (GH 26198)

  • IndexRangeIndex を numpy の min および max 関数に渡せるようにしました (GH 26125)

  • Series サブクラスの空のオブジェクトの repr で実際のクラス名を使用する (GH 27001)。

  • タイムゾーンを認識する datetime オブジェクトのオブジェクト配列を渡すと、誤って ValueError が発生する DataFrame のバグ (GH 13287)

貢献者#

このリリースには合計231人がパッチを貢献しました。「+」の記号がある人は初めてパッチを貢献しました。

  • 1_x7 +

  • Abdullah İhsan Seçer +

  • Adam Bull +

  • Adam Hooper

  • アルバート・ビラノバ・デル・モラル

  • Alex Watt +

  • AlexTereshenkov +

  • Alexander Buchkovsky

  • Alexander Hendorf +

  • Alexander Nordin +

  • Alexander Ponomaroff

  • Alexandre Batisse +

  • Alexandre Decan +

  • Allen Downey +

  • Alyssa Fu Ward +

  • Andrew Gaspari +

  • Andrew Wood +

  • Antoine Viscardi +

  • Antonio Gutierrez +

  • Arno Veenstra +

  • ArtinSarraf

  • Batalex +

  • Baurzhan Muftakhidinov

  • Benjamin Rowell

  • Bharat Raghunathan +

  • Bhavani Ravi +

  • Big Head +

  • Brett Randall +

  • Bryan Cutler +

  • C John Klehm +

  • Caleb Braun +

  • Cecilia +

  • Chris Bertinato +

  • Chris Stadler +

  • Christian Haege +

  • Christian Hudon

  • クリストファー・ウィーラン

  • Chuanzhu Xu +

  • Clemens Brunner

  • Damian Kula +

  • Daniel Hrisca +

  • Daniel Luis Costa +

  • ダニエル・サクストン

  • DanielFEvans +

  • David Liu +

  • Deepyaman Datta +

  • Denis Belavin +

  • Devin Petersohn +

  • Diane Trout +

  • EdAbati +

  • Enrico Rotundo +

  • EternalLearner42 +

  • Evan +

  • Evan Livelo +

  • Fabian Rost +

  • Flavien Lambert +

  • Florian Rathgeber +

  • Frank Hoang +

  • Gaibo Zhang +

  • Gioia Ballin

  • Giuseppe Romagnuolo +

  • Gordon Blackadder +

  • Gregory Rome +

  • ギョーム・ゲイ

  • HHest +

  • Hielke Walinga +

  • How Si Wei +

  • Hubert

  • Huize Wang +

  • Hyukjin Kwon +

  • Ian Dunn +

  • Inevitable-Marzipan +

  • アーブ・ラスティッグ

  • JElfner +

  • Jacob Bundgaard +

  • James Cobon-Kerr +

  • Jan-Philip Gehrcke +

  • Jarrod Millman +

  • Jayanth Katuri +

  • ジェフ・リーバック

  • ジェレミー・シェンデル

  • Jiang Yue +

  • Joel Ostblom

  • Johan von Forstner +

  • Johnny Chiu +

  • Jonas +

  • Jonathon Vandezande +

  • Jop Vermeer +

  • Joris Van den Bossche

  • ジョシュ

  • Josh Friedlander +

  • ジャスティン・ジェン

  • Kaiqi Dong

  • Kane +

  • Kapil Patel +

  • Kara de la Marck +

  • Katherine Surta +

  • Katrin Leinweber +

  • ケンドール・マッセ

  • ケビン・シェパード

  • Kyle Kosic +

  • Lorenzo Stella +

  • Maarten Rietbergen +

  • Mak Sze Chun

  • Marc Garcia

  • Mateusz Woś

  • Matias Heikkilä

  • Mats Maiwald +

  • Matthew Roeschke

  • Max Bolingbroke +

  • Max Kovalovs +

  • Max van Deursen +

  • Michael

  • Michael Davis +

  • Michael P. Moran +

  • Mike Cramblett +

  • Min ho Kim +

  • Misha Veldhoen +

  • Mukul Ashwath Ram +

  • MusTheDataGuy +

  • Nanda H Krishna +

  • Nicholas Musolino

  • Noam Hershtig +

  • Noora Husseini +

  • Paul

  • Paul Reidy

  • Pauli Virtanen

  • Pav A +

  • Peter Leimbigler +

  • Philippe Ombredanne +

  • ピエトロ・バティストン

  • Richard Eames +

  • Roman Yurchak

  • Ruijing Li

  • Ryan

  • Ryan Joyce +

  • Ryan Nazareth

  • Ryan Rehman +

  • Sakar Panta +

  • Samuel Sinayoko

  • Sandeep Pathak +

  • Sangwoong Yoon

  • Saurav Chakravorty

  • Scott Talbert +

  • Sergey Kopylov +

  • Shantanu Gontia +

  • Shivam Rana +

  • Shorokhov Sergey +

  • Simon Hawkins

  • Soyoun(Rose) Kim

  • ステファン・ホイヤー

  • Stephen Cowley +

  • Stephen Rauch

  • Sterling Paramore +

  • Steven +

  • スティン・ヴァン・ホーイ

  • Sumanau Sareen +

  • Takuya N +

  • Tan Tran +

  • Tao He +

  • Tarbo Fukazawa

  • Terji Petersen +

  • Thein Oo

  • ThibTrip +

  • Thijs Damsma +

  • Thiviyan Thanapalasingam

  • トーマス・A・キャスウェル

  • Thomas Kluiters +

  • Tilen Kusterle +

  • Tim Gates +

  • Tim Hoffmann

  • Tim Swast

  • Tom Augspurger

  • Tom Neep +

  • Tomáš Chvátal +

  • Tyler Reddy

  • Vaibhav Vishal +

  • Vasily Litvinov +

  • Vibhu Agarwal +

  • Vikramjeet Das +

  • Vladislav +

  • Víctor Moron Tejero +

  • Wenhuan

  • Will Ayd +

  • ウィリアム・エイド

  • Wouter De Coster +

  • Yoann Goular +

  • Zach Angell +

  • alimcmaster1

  • anmyachev +

  • クリス・B1

  • danielplawrence +

  • endenis +

  • enisnazif +

  • ezcitron +

  • fjetter

  • froessler

  • ジーエフヤング

  • gwrome +

  • h-vetinari

  • haison +

  • hannah-c +

  • heckeop +

  • iamshwin +

  • jamesoliverh +

  • jbrockmendel

  • jkovacevic +

  • killerontherun1 +

  • knuu +

  • kpapdac +

  • kpflugshaupt +

  • krsnik93 +

  • leerssej +

  • lrjball +

  • mazayo +

  • nathalier +

  • nrebena +

  • nullptr +

  • pilkibun +

  • pmaxey83 +

  • rbenes +

  • robbuckley

  • shawnbrown +

  • sudhir mohanraj +

  • tadeja +

  • tamuhey +

  • thatneat

  • topper-123

  • willweil +

  • yehia67 +

  • yhaque1213 +