バージョン 0.15.0 (2014年10月18日)#

これは 0.14.1 からのメジャーリリースであり、少数のAPI変更、いくつかの新機能、機能強化、パフォーマンス改善に加え、多数のバグ修正が含まれています。すべてのユーザーにこのバージョンへのアップグレードをお勧めします。

警告

pandas >= 0.15.0 は NumPy バージョン < 1.7.0 との互換性をサポートしなくなります。最新バージョンの pandas を使用したい場合は、NumPy >= 1.7.0 にアップグレードしてください (GH 7711)

  • 主な機能は以下の通りです。

    • Categorical 型がファーストクラスの pandas 型として統合されました。こちらを参照してください。

    • 新しいスカラ型 Timedelta と新しいインデックス型 TimedeltaIndex が追加されました。こちらを参照してください。

    • Series の新しい datetime ライクなプロパティアクセサー .dt が追加されました。Datetimelike Propertiesを参照してください。

    • df.info() の新しい DataFrame デフォルト表示にはメモリ使用量が含まれるようになりました。Memory Usageを参照してください。

    • read_csv は解析時にデフォルトで空行を無視するようになりました。こちらを参照してください。

    • セット演算でインデックスを使用する際のAPI変更。こちらを参照してください。

    • タイムゾーン処理の強化。こちらを参照してください。

    • 移動平均および拡張モーメント関数の多数の改善。こちらを参照してください。

    • Index クラスの内部リファクタリングにより、ndarray のサブクラスではなくなりました。Internal Refactoringを参照してください。

    • バージョン 3.0.0 未満の PyTables およびバージョン 2.1 未満の numexpr のサポートを終了しました (GH 7990)

    • インデックスのドキュメントをIndexing and Selecting DataMultiIndex / Advanced Indexingに分割しました。

    • 文字列メソッドのドキュメントをWorking with Text Dataに分割しました。

  • 更新する前にAPI Changesdeprecationsを確認してください。

  • その他の機能強化

  • パフォーマンス改善

  • バグ修正

警告

0.15.0 では、Index は内部的に ndarray のサブクラスではなく、他の pandas オブジェクトと同様に PandasObject のサブクラスになるようにリファクタリングされました。この変更により、新しいインデックス型のサブクラス化と作成が非常に容易になります。これは非常に限られたAPIへの影響 ( Internal Refactoringを参照) しか持たない透過的な変更であるはずです。

警告

Categorical のリファクタリングにより、2引数のコンストラクタが「コード/ラベルとレベル」から「値とレベル(現在は「カテゴリ」と呼ばれる)」に変更されました。これは微妙なバグにつながる可能性があります。Categorical を直接使用している場合は、この pandas バージョンに更新する前にコードを監査し、from_codes() コンストラクタを使用するように変更してください。Categorical の詳細についてはこちらを参照してください。

新機能#

Series/DataFrame内のカテゴリ#

CategoricalSeries および DataFrames に含めることができるようになり、操作するための新しいメソッドが追加されました。このAPI/実装の多くは Jan Schulz 氏に感謝します。( GH 3943, GH 5313, GH 5314, GH 7444, GH 7839, GH 7848, GH 7864, GH 7914, GH 7768, GH 8006, GH 3678, GH 8075, GH 8076, GH 8143, GH 8453, GH 8518)。

完全なドキュメントについては、カテゴリの紹介API ドキュメントを参照してください。

In [1]: df = pd.DataFrame({"id": [1, 2, 3, 4, 5, 6],
   ...:                    "raw_grade": ['a', 'b', 'b', 'a', 'a', 'e']})
   ...: 

In [2]: df["grade"] = df["raw_grade"].astype("category")

In [3]: df["grade"]
Out[3]: 
0    a
1    b
2    b
3    a
4    a
5    e
Name: grade, Length: 6, dtype: category
Categories (3, object): ['a', 'b', 'e']

# Rename the categories
In [4]: df["grade"] = df["grade"].cat.rename_categories(["very good", "good", "very bad"])

# Reorder the categories and simultaneously add the missing categories
In [5]: df["grade"] = df["grade"].cat.set_categories(["very bad", "bad",
   ...:                                               "medium", "good", "very good"])
   ...: 

In [6]: df["grade"]
Out[6]: 
0    very good
1         good
2         good
3    very good
4    very good
5     very bad
Name: grade, Length: 6, dtype: category
Categories (5, object): ['very bad', 'bad', 'medium', 'good', 'very good']

In [7]: df.sort_values("grade")
Out[7]: 
   id raw_grade      grade
5   6         e   very bad
1   2         b       good
2   3         b       good
0   1         a  very good
3   4         a  very good
4   5         a  very good

[6 rows x 3 columns]

In [8]: df.groupby("grade", observed=False).size()
Out[8]: 
grade
very bad     1
bad          0
medium       0
good         2
very good    3
Length: 5, dtype: int64
  • pandas.core.group_agg および pandas.core.factor_agg は削除されました。代わりに、データフレームを構築し、df.groupby(<group>).agg(<func>) を使用してください。

  • Categorical コンストラクタに「コード/ラベルとレベル」を供給することはサポートされなくなりました。コンストラクタに2つの引数を供給することは、「値とレベル(現在は「カテゴリ」と呼ばれる)」と解釈されます。from_codes() コンストラクタを使用するようにコードを変更してください。

  • Categorical.labels 属性は Categorical.codes に名前が変更され、読み取り専用です。コードを操作したい場合は、Categoricals の API メソッドのいずれかを使用してください。

  • Categorical.levels 属性は Categorical.categories に名前が変更されました。

TimedeltaIndex/scalar#

Timedelta という新しいスカラ型を導入します。これは datetime.timedelta のサブクラスであり、同様に振る舞いますが、np.timedelta64 型との互換性や、多数のカスタム表現、解析、属性を可能にします。この型は Timestampdatetimes に対して機能するのと非常によく似ています。これは型のための優れたAPIボックスです。ドキュメントを参照してください。( GH 3009, GH 4533, GH 8209, GH 8187, GH 8190, GH 7869, GH 7661, GH 8345, GH 8471)

警告

Timedelta スカラ(および TimedeltaIndex )のコンポーネントフィールドは、datetime.timedelta オブジェクトのコンポーネントフィールドとは 異なります。例えば、datetime.timedelta オブジェクトの .seconds は、hours, minutes, seconds を組み合わせた合計秒数を返します。対照的に、pandas の Timedelta は、時間、分、マイクロ秒、ナノ秒を個別に分離します。

# Timedelta accessor
In [9]: tds = pd.Timedelta('31 days 5 min 3 sec')

In [10]: tds.minutes
Out[10]: 5L

In [11]: tds.seconds
Out[11]: 3L

# datetime.timedelta accessor
# this is 5 minutes * 60 + 3 seconds
In [12]: tds.to_pytimedelta().seconds
Out[12]: 303

注意: これは v0.16.0 以降では真ではなく、datetime.timedelta との完全な互換性が導入されています。0.16.0 whatsnew エントリを参照してください。

警告

0.15.0 より前は、pd.to_timedelta はリストライク/Series 入力に対しては Series を返し、スカラ入力に対しては np.timedelta64 を返していました。現在は、リストライク入力に対しては TimedeltaIndex を、Series 入力に対しては Series を、スカラ入力に対しては Timedelta を返すようになりました。

pd.to_timedelta の引数は、以前は (arg,box=True,unit='ns') でしたが、より論理的であるため、現在は (arg,unit='ns',box=True,coerce=False) となっています。

スカラを構築

In [9]: pd.Timedelta('1 days 06:05:01.00003')
Out[9]: Timedelta('1 days 06:05:01.000030')

In [10]: pd.Timedelta('15.5us')
Out[10]: Timedelta('0 days 00:00:00.000015500')

In [11]: pd.Timedelta('1 hour 15.5us')
Out[11]: Timedelta('0 days 01:00:00.000015500')

# negative Timedeltas have this string repr
# to be more consistent with datetime.timedelta conventions
In [12]: pd.Timedelta('-1us')
Out[12]: Timedelta('-1 days +23:59:59.999999')

# a NaT
In [13]: pd.Timedelta('nan')
Out[13]: NaT

Timedelta のフィールドにアクセス

In [14]: td = pd.Timedelta('1 hour 3m 15.5us')

In [15]: td.seconds
Out[15]: 3780

In [16]: td.microseconds
Out[16]: 15

In [17]: td.nanoseconds
Out[17]: 500

TimedeltaIndex を構築

In [18]: pd.TimedeltaIndex(['1 days', '1 days, 00:00:05',
   ....:                    np.timedelta64(2, 'D'),
   ....:                    datetime.timedelta(days=2, seconds=2)])
   ....: 
Out[18]: 
TimedeltaIndex(['1 days 00:00:00', '1 days 00:00:05', '2 days 00:00:00',
                '2 days 00:00:02'],
               dtype='timedelta64[ns]', freq=None)

通常の範囲で TimedeltaIndex を構築する

In [19]: pd.timedelta_range('1 days', periods=5, freq='D')
Out[19]: TimedeltaIndex(['1 days', '2 days', '3 days', '4 days', '5 days'], dtype='timedelta64[ns]', freq='D')
In [20]: pd.timedelta_range(start='1 days', end='2 days', freq='30T')
Out[20]:
TimedeltaIndex(['1 days 00:00:00', '1 days 00:30:00', '1 days 01:00:00',
                '1 days 01:30:00', '1 days 02:00:00', '1 days 02:30:00',
                '1 days 03:00:00', '1 days 03:30:00', '1 days 04:00:00',
                '1 days 04:30:00', '1 days 05:00:00', '1 days 05:30:00',
                '1 days 06:00:00', '1 days 06:30:00', '1 days 07:00:00',
                '1 days 07:30:00', '1 days 08:00:00', '1 days 08:30:00',
                '1 days 09:00:00', '1 days 09:30:00', '1 days 10:00:00',
                '1 days 10:30:00', '1 days 11:00:00', '1 days 11:30:00',
                '1 days 12:00:00', '1 days 12:30:00', '1 days 13:00:00',
                '1 days 13:30:00', '1 days 14:00:00', '1 days 14:30:00',
                '1 days 15:00:00', '1 days 15:30:00', '1 days 16:00:00',
                '1 days 16:30:00', '1 days 17:00:00', '1 days 17:30:00',
                '1 days 18:00:00', '1 days 18:30:00', '1 days 19:00:00',
                '1 days 19:30:00', '1 days 20:00:00', '1 days 20:30:00',
                '1 days 21:00:00', '1 days 21:30:00', '1 days 22:00:00',
                '1 days 22:30:00', '1 days 23:00:00', '1 days 23:30:00',
                '2 days 00:00:00'],
               dtype='timedelta64[ns]', freq='30T')

これで TimedeltaIndex をpandasオブジェクトのインデックスとして使用できます。

In [20]: s = pd.Series(np.arange(5),
   ....:               index=pd.timedelta_range('1 days', periods=5, freq='s'))
   ....: 

In [21]: s
Out[21]: 
1 days 00:00:00    0
1 days 00:00:01    1
1 days 00:00:02    2
1 days 00:00:03    3
1 days 00:00:04    4
Freq: s, Length: 5, dtype: int64

部分的な文字列選択で選択できます。

In [22]: s['1 day 00:00:02']
Out[22]: 2

In [23]: s['1 day':'1 day 00:00:02']
Out[23]: 
1 days 00:00:00    0
1 days 00:00:01    1
1 days 00:00:02    2
Freq: s, Length: 3, dtype: int64

最後に、TimedeltaIndexDatetimeIndex の組み合わせにより、NaT を保持する特定の組み合わせ操作が可能になります。

In [24]: tdi = pd.TimedeltaIndex(['1 days', pd.NaT, '2 days'])

In [25]: tdi.tolist()
Out[25]: [Timedelta('1 days 00:00:00'), NaT, Timedelta('2 days 00:00:00')]

In [26]: dti = pd.date_range('20130101', periods=3)

In [27]: dti.tolist()
Out[27]: 
[Timestamp('2013-01-01 00:00:00'),
 Timestamp('2013-01-02 00:00:00'),
 Timestamp('2013-01-03 00:00:00')]

In [28]: (dti + tdi).tolist()
Out[28]: [Timestamp('2013-01-02 00:00:00'), NaT, Timestamp('2013-01-05 00:00:00')]

In [29]: (dti - tdi).tolist()
Out[29]: [Timestamp('2012-12-31 00:00:00'), NaT, Timestamp('2013-01-01 00:00:00')]
  • timedelta64[ns]Series (例: list(Series(...))) のイテレーションは、v0.15.0 より前では各要素に対して np.timedelta64 を返していました。これらは現在 Timedelta でラップされます。

メモリ使用量#

DataFrame のメモリ使用量を見つけるメソッドを実装しました。詳細についてはFAQを参照してください。( GH 6852)

新しい表示オプション display.memory_usage (Options and settings を参照) は、df.info() メソッドの memory_usage 引数のデフォルト動作を設定します。デフォルトでは、display.memory_usageTrue です。

In [30]: dtypes = ['int64', 'float64', 'datetime64[ns]', 'timedelta64[ns]',
   ....:           'complex128', 'object', 'bool']
   ....: 

In [31]: n = 5000

In [32]: data = {t: np.random.randint(100, size=n).astype(t) for t in dtypes}

In [33]: df = pd.DataFrame(data)

In [34]: df['categorical'] = df['object'].astype('category')

In [35]: df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5000 entries, 0 to 4999
Data columns (total 8 columns):
 #   Column           Non-Null Count  Dtype          
---  ------           --------------  -----          
 0   int64            5000 non-null   int64          
 1   float64          5000 non-null   float64        
 2   datetime64[ns]   5000 non-null   datetime64[ns] 
 3   timedelta64[ns]  5000 non-null   timedelta64[ns]
 4   complex128       5000 non-null   complex128     
 5   object           5000 non-null   object         
 6   bool             5000 non-null   bool           
 7   categorical      5000 non-null   category       
dtypes: bool(1), category(1), complex128(1), datetime64[ns](1), float64(1), int64(1), object(1), timedelta64[ns](1)
memory usage: 288.2+ KB

さらに、memory_usage() は、各列のメモリ使用量を返すデータフレームオブジェクトの利用可能なメソッドです。

In [36]: df.memory_usage(index=True)
Out[36]: 
Index                128
int64              40000
float64            40000
datetime64[ns]     40000
timedelta64[ns]    40000
complex128         80000
object             40000
bool                5000
categorical         9968
Length: 9, dtype: int64

Series.dt accessor#

Series は、それが datetime/period ライクな Series である場合、Series の の datetime ライクなプロパティを簡潔に返すアクセサーを獲得しました。( GH 7207) これは、既存の Series と同様にインデックス付けされた Series を返します。ドキュメントを参照してください。

# datetime
In [37]: s = pd.Series(pd.date_range('20130101 09:10:12', periods=4))

In [38]: s
Out[38]: 
0   2013-01-01 09:10:12
1   2013-01-02 09:10:12
2   2013-01-03 09:10:12
3   2013-01-04 09:10:12
Length: 4, dtype: datetime64[ns]

In [39]: s.dt.hour
Out[39]: 
0    9
1    9
2    9
3    9
Length: 4, dtype: int32

In [40]: s.dt.second
Out[40]: 
0    12
1    12
2    12
3    12
Length: 4, dtype: int32

In [41]: s.dt.day
Out[41]: 
0    1
1    2
2    3
3    4
Length: 4, dtype: int32

In [42]: s.dt.freq
Out[42]: 'D'

これにより、このような素晴らしい表現が可能になります。

In [43]: s[s.dt.day == 2]
Out[43]: 
1   2013-01-02 09:10:12
Length: 1, dtype: datetime64[ns]

タイムゾーン対応変換を簡単に生成できます。

In [44]: stz = s.dt.tz_localize('US/Eastern')

In [45]: stz
Out[45]: 
0   2013-01-01 09:10:12-05:00
1   2013-01-02 09:10:12-05:00
2   2013-01-03 09:10:12-05:00
3   2013-01-04 09:10:12-05:00
Length: 4, dtype: datetime64[ns, US/Eastern]

In [46]: stz.dt.tz
Out[46]: <DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>

これらの種類の操作を連結することもできます。

In [47]: s.dt.tz_localize('UTC').dt.tz_convert('US/Eastern')
Out[47]: 
0   2013-01-01 04:10:12-05:00
1   2013-01-02 04:10:12-05:00
2   2013-01-03 04:10:12-05:00
3   2013-01-04 04:10:12-05:00
Length: 4, dtype: datetime64[ns, US/Eastern]

.dt アクセサーは period および timedelta の dtypes で機能します。

# period
In [48]: s = pd.Series(pd.period_range('20130101', periods=4, freq='D'))

In [49]: s
Out[49]: 
0    2013-01-01
1    2013-01-02
2    2013-01-03
3    2013-01-04
Length: 4, dtype: period[D]

In [50]: s.dt.year
Out[50]: 
0    2013
1    2013
2    2013
3    2013
Length: 4, dtype: int64

In [51]: s.dt.day
Out[51]: 
0    1
1    2
2    3
3    4
Length: 4, dtype: int64
# timedelta
In [52]: s = pd.Series(pd.timedelta_range('1 day 00:00:05', periods=4, freq='s'))

In [53]: s
Out[53]: 
0   1 days 00:00:05
1   1 days 00:00:06
2   1 days 00:00:07
3   1 days 00:00:08
Length: 4, dtype: timedelta64[ns]

In [54]: s.dt.days
Out[54]: 
0    1
1    1
2    1
3    1
Length: 4, dtype: int64

In [55]: s.dt.seconds
Out[55]: 
0    5
1    6
2    7
3    8
Length: 4, dtype: int32

In [56]: s.dt.components
Out[56]: 
   days  hours  minutes  seconds  milliseconds  microseconds  nanoseconds
0     1      0        0        5             0             0            0
1     1      0        0        6             0             0            0
2     1      0        0        7             0             0            0
3     1      0        0        8             0             0            0

[4 rows x 7 columns]

タイムゾーン処理の改善#

  • タイムゾーン対応の Timestamp および DatetimeIndex に対して tz_localize(None) を実行すると、タイムゾーンがローカル時間を保持したまま削除されるようになりました。以前は Exception または TypeError が発生していました (GH 7812)

    In [58]: ts = pd.Timestamp('2014-08-01 09:00', tz='US/Eastern')
    
    In[59]: ts
    Out[59]: Timestamp('2014-08-01 09:00:00-0400', tz='US/Eastern')
    
    In [60]: ts.tz_localize(None)
    Out[60]: Timestamp('2014-08-01 09:00:00')
    
    In [61]: didx = pd.date_range(start='2014-08-01 09:00', freq='H',
       ....:                      periods=10, tz='US/Eastern')
       ....:
    
    In [62]: didx
    Out[62]:
    DatetimeIndex(['2014-08-01 09:00:00-04:00', '2014-08-01 10:00:00-04:00',
                   '2014-08-01 11:00:00-04:00', '2014-08-01 12:00:00-04:00',
                   '2014-08-01 13:00:00-04:00', '2014-08-01 14:00:00-04:00',
                   '2014-08-01 15:00:00-04:00', '2014-08-01 16:00:00-04:00',
                   '2014-08-01 17:00:00-04:00', '2014-08-01 18:00:00-04:00'],
                  dtype='datetime64[ns, US/Eastern]', freq='H')
    
    In [63]: didx.tz_localize(None)
    Out[63]:
    DatetimeIndex(['2014-08-01 09:00:00', '2014-08-01 10:00:00',
                   '2014-08-01 11:00:00', '2014-08-01 12:00:00',
                   '2014-08-01 13:00:00', '2014-08-01 14:00:00',
                   '2014-08-01 15:00:00', '2014-08-01 16:00:00',
                   '2014-08-01 17:00:00', '2014-08-01 18:00:00'],
                  dtype='datetime64[ns]', freq=None)
    
  • tz_localizeambiguous キーワードを受け入れるようになりました。これにより、日付がDSTに属するかどうかを示すブール値の配列を渡したり、遷移時間をNaTに設定するために「NaT」を渡したり、DST/非DSTを推測するために「infer」を渡したり、AmbiguousTimeError を発生させるために「raise」(デフォルト)を渡したりできます。詳細についてはドキュメントを参照してください (GH 7943)

  • DataFrame.tz_localizeDataFrame.tz_convert は、MultiIndex の特定のレベルをローカライズするためのオプションの level 引数を受け入れるようになりました (GH 7846)

  • Timestamp.tz_localize および Timestamp.tz_convert は、エラーケースで以前の Exception ではなく TypeError を発生させるようになりました (GH 8025)

  • UTC にローカライズされた時系列/インデックスは、Series/DataFrame に挿入されると、object dtype として UTC タイムゾーンを保持します (以前は naive な datetime64[ns] になっていました) (GH 8411)

  • Timestamp.__repr__dateutil.tz.tzoffset 情報を表示します (GH 7907)

移動/拡張モーメントの改善#

  • rolling_min(), rolling_max(), rolling_cov(), および rolling_corr() は、len(arg) < min_periods <= window の場合に例外を発生させるのではなく、すべて NaN のオブジェクトを返すようになりました。(これにより、すべてのローリング関数がこの動作で一貫するようになります)。(GH 7766)

    0.15.0 より前

    In [57]: s = pd.Series([10, 11, 12, 13])
    
    In [15]: pd.rolling_min(s, window=10, min_periods=5)
    ValueError: min_periods (5) must be <= window (4)
    

    新しい動作

    In [4]: pd.rolling_min(s, window=10, min_periods=5)
    Out[4]:
    0   NaN
    1   NaN
    2   NaN
    3   NaN
    dtype: float64
    
  • rolling_max(), rolling_min(), rolling_sum(), rolling_mean(), rolling_median(), rolling_std(), rolling_var(), rolling_skew(), rolling_kurt(), rolling_quantile(), rolling_cov(), rolling_corr(), rolling_corr_pairwise(), rolling_window(), および rolling_apply()center=True を指定した場合、以前は入力 arg と同じ構造の結果を返し、最後の (window-1)/2 エントリには NaN が入っていました。

    現在では、結果の最後の (window-1)/2 エントリは、入力 arg の後に (window-1)/2 個の NaN 値が続く場合と同様に計算されます (または、rolling_apply() の場合はウィンドウが縮小する場合)。(GH 7925, GH 8269)

    以前の動作 (最後の値が NaN であることに注意)

    In [7]: pd.rolling_sum(Series(range(4)), window=3, min_periods=0, center=True)
    Out[7]:
    0     1
    1     3
    2     6
    3   NaN
    dtype: float64
    

    新しい動作 (最後の値が 5 = sum([2, 3, NaN]) であることに注意)

    In [7]: pd.rolling_sum(pd.Series(range(4)), window=3,
      ....:                min_periods=0, center=True)
    Out[7]:
    0    1
    1    3
    2    6
    3    5
    dtype: float64
    
  • rolling_window() は、移動平均モード (mean=True) で重みを適切に正規化するようになりました。これにより、計算された加重平均 (例: 'triang'、'gaussian') は、重みなしで計算された平均 (つまり 'boxcar') と同じ平均の周りに分布します。詳細については、正規化に関する注意を参照してください。( GH 7618)

    In [58]: s = pd.Series([10.5, 8.8, 11.4, 9.7, 9.3])
    

    0.15.0 以前の動作

    In [39]: pd.rolling_window(s, window=3, win_type='triang', center=True)
    Out[39]:
    0         NaN
    1    6.583333
    2    6.883333
    3    6.683333
    4         NaN
    dtype: float64
    

    新しい動作

    In [10]: pd.rolling_window(s, window=3, win_type='triang', center=True)
    Out[10]:
    0       NaN
    1     9.875
    2    10.325
    3    10.025
    4       NaN
    dtype: float64
    
  • すべての expanding_ 関数から center 引数を削除しました (リストを参照)。center=True の場合に生成される結果はあまり意味がなかったためです。( GH 7925)

  • expanding_cov()rolling_cov() にオプションの ddof 引数を追加しました。デフォルト値の 1 は後方互換性があります。( GH 8279)

  • expanding_var(), expanding_std(), rolling_var(), および rolling_std()ddof 引数を文書化しました。これらの関数が ddof 引数 (デフォルト値は 1) をサポートすることは、以前は文書化されていませんでした。( GH 8064)

  • ewma(), ewmstd(), ewmvol(), ewmvar(), ewmcov(), および ewmcorr() は、rolling_*() および expanding_*() 関数と同様に min_periods を解釈するようになりました。つまり、指定された結果のエントリは、(この場合、拡張) ウィンドウに少なくとも min_periods の値が含まれていない場合、NaN になります。以前の動作は、最初の非 NaN 値から始まる min_periods のエントリを NaN に設定することでした。( GH 7977)

    以前の動作 (値がインデックス 2 から始まることに注意。これは最初の空でない値のインデックス 0min_periods 後)

    In [59]: s  = pd.Series([1, None, None, None, 2, 3])
    
    In [51]: pd.ewma(s, com=3., min_periods=2)
    Out[51]:
    0         NaN
    1         NaN
    2    1.000000
    3    1.000000
    4    1.571429
    5    2.189189
    dtype: float64
    

    新しい動作 (値がインデックス 4 から始まることに注意。min_periods=2 なので、2番目の空でない値の位置)

    In [2]: pd.ewma(s, com=3., min_periods=2)
    Out[2]:
    0         NaN
    1         NaN
    2         NaN
    3         NaN
    4    1.759644
    5    2.383784
    dtype: float64
    
  • ewmstd(), ewmvol(), ewmvar(), ewmcov(), および ewmcorr() には、ewma() と同様に、重みの計算方法に影響を与えるオプションの adjust 引数が追加されました。adjust のデフォルト値は True であり、これは後方互換性があります。詳細については、指数加重モーメント関数を参照してください。( GH 7911)

  • ewma(), ewmstd(), ewmvol(), ewmvar(), ewmcov(), および ewmcorr() は、オプションの ignore_na 引数を取るようになりました。ignore_na=False (デフォルト) の場合、欠損値は重み計算で考慮されます。ignore_na=True (0.15.0 以前の動作を再現) の場合、欠損値は重み計算で無視されます。( GH 7543)

    In [7]: pd.ewma(pd.Series([None, 1., 8.]), com=2.)
    Out[7]:
    0    NaN
    1    1.0
    2    5.2
    dtype: float64
    
    In [8]: pd.ewma(pd.Series([1., None, 8.]), com=2.,
      ....:         ignore_na=True)  # pre-0.15.0 behavior
    Out[8]:
    0    1.0
    1    1.0
    2    5.2
    dtype: float64
    
    In [9]: pd.ewma(pd.Series([1., None, 8.]), com=2.,
      ....:         ignore_na=False)  # new default
    Out[9]:
    0    1.000000
    1    1.000000
    2    5.846154
    dtype: float64
    

    警告

    デフォルト (ignore_na=False) では、欠損値が存在する場合の ewm*() 関数の重み計算は、0.15.0 以前のバージョンとは異なります。欠損値が存在する場合の 0.15.0 以前の重み計算を再現するには、明示的に ignore_na=True を指定する必要があります。

  • expanding_cov()expanding_corr()rolling_cov()rolling_cor()ewmcov()、および ewmcorr() で、結果の列が名前でソートされ、重複する列でエラーが発生するバグが修正されました。現在は重複しない列を処理し、元の順序で列を返します(ただし、pairwise=False の2つの DataFrame の場合は動作は変更されません)(GH 7542)

  • rolling_count() および expanding_*() 関数で、ゼロ長データに対して不必要にエラーメッセージが生成されるバグが修正されました (GH 8056)

  • rolling_apply() および expanding_apply() で、min_periods=0min_periods=1 と解釈するバグが修正されました (GH 8080)

  • expanding_std() および expanding_var() で、単一の値に対して混乱を招くエラーメッセージが生成されるバグが修正されました (GH 7900)

  • rolling_std() および rolling_var() で、単一の値に対して NaN ではなく 0 が生成されるバグが修正されました (GH 7900)

  • ewmstd(), ewmvol(), ewmvar(), および ewmcov() で、bias=False (デフォルト) の場合のバイアス除去係数の計算におけるバグが修正されました。以前は、adjust=Trueignore_na=True、および無限の観測数に基づく誤った定数係数が使用されていました。現在では、実際の重みに基づいて各エントリに異なる係数 (通常の N/(N-1) 係数に類似) が使用されます。特に、単一の点に対して bias=False の場合、NaN の値が返されますが、以前は (およそ) 0 の値が返されていました。

    たとえば、ewmvar(..., bias=False) の 0.15.0 以前の結果と、対応するバイアス除去係数を考えてみましょう。

    In [60]: s = pd.Series([1., 2., 0., 4.])
    
    In [89]: pd.ewmvar(s, com=2., bias=False)
    Out[89]:
    0   -2.775558e-16
    1    3.000000e-01
    2    9.556787e-01
    3    3.585799e+00
    dtype: float64
    
    In [90]: pd.ewmvar(s, com=2., bias=False) / pd.ewmvar(s, com=2., bias=True)
    Out[90]:
    0    1.25
    1    1.25
    2    1.25
    3    1.25
    dtype: float64
    

    エントリ 0 が約 0 であり、バイアス除去係数が定数 1.25 であることに注意してください。比較すると、以下の 0.15.0 の結果ではエントリ 0NaN であり、バイアス除去係数は減少しています (1.25 に向かって)

    In [14]: pd.ewmvar(s, com=2., bias=False)
    Out[14]:
    0         NaN
    1    0.500000
    2    1.210526
    3    4.089069
    dtype: float64
    
    In [15]: pd.ewmvar(s, com=2., bias=False) / pd.ewmvar(s, com=2., bias=True)
    Out[15]:
    0         NaN
    1    2.083333
    2    1.583333
    3    1.425439
    dtype: float64
    

    詳細については、指数加重モーメント関数を参照してください。( GH 7912)

SQL IOモジュールの改善#

  • to_sql 関数に chunksize パラメータのサポートを追加しました。これにより、DataFrame をチャンク単位で書き込み、パケットサイズオーバーフローエラーを回避できます (GH 8062)。

  • read_sql 関数に chunksize パラメータのサポートを追加しました。この引数を指定すると、クエリ結果のチャンクを介したイテレータが返されます (GH 2908)。

  • to_sqldatetime.date および datetime.time オブジェクト列の書き込みをサポートしました (GH 6932)。

  • read_sql_table および to_sql で読み書きする schema を指定するサポートを追加しました (GH 7441, GH 7952)。例えば

    df.to_sql('table', engine, schema='other_schema')  # noqa F821
    pd.read_sql_table('table', engine, schema='other_schema')  # noqa F821
    
  • to_sqlNaN 値の書き込みをサポートしました (GH 2754)。

  • to_sql で、すべてのデータベースフレーバーに対して datetime64 列の書き込みをサポートしました (GH 7103)。

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

破壊的変更#

Categorical に関連するAPI変更 (詳細はこちら)

  • 2つの引数を持つ Categorical コンストラクタは、「コード/ラベルとレベル」から「値とレベル(現在は「カテゴリ」と呼ばれる)」に変更されました。これは微妙なバグにつながる可能性があります。Categorical を直接使用している場合は、from_codes() コンストラクタを使用するように変更してコードを監査してください。

    以前の関数呼び出し (0.15.0 以前)

    pd.Categorical([0,1,0,2,1], levels=['a', 'b', 'c'])
    

    同じ動作を維持するために、以下のように変更する必要があります。

    In [2]: pd.Categorical.from_codes([0,1,0,2,1], categories=['a', 'b', 'c'])
    Out[2]:
    [a, b, a, c, b]
    Categories (3, object): [a, b, c]
    

Timedelta スカラの導入に関連するAPI変更 (上記を参照)

  • 0.15.0 より前は、to_timedelta() はリストライク/Series 入力に対しては Series を返し、スカラ入力に対しては np.timedelta64 を返していました。現在は、リストライク入力に対しては TimedeltaIndex を、Series 入力に対しては Series を、スカラ入力に対しては Timedelta を返すようになりました。

移動および拡張関数に関連するAPI変更については、上記の詳細な概要を参照してください。

その他の注目すべきAPI変更

  • .loc とリストライクなインデクサを使用してインデックスを付け、値が見つからない場合の一貫性。

    In [61]: df = pd.DataFrame([['a'], ['b']], index=[1, 2])
    
    In [62]: df
    Out[62]: 
       0
    1  a
    2  b
    
    [2 rows x 1 columns]
    

    以前のバージョンでは、これら2つの構造には違いがありました。

    • df.loc[[3]] は3で再インデックス付けされたフレームを返しました (すべての np.nan 値を含む)。

    • df.loc[[3],:]KeyError を発生させました。

    両方とも KeyError を発生させるようになりました。ルールは、リストライクと .loc を使用する場合、少なくとも1つ のインデクサが見つかる必要があるというものです (GH 7999)

    さらに、以前のバージョンではこれらも異なっていました。

    • df.loc[[1,3]] は [1,3] で再インデックス付けされたフレームを返しました。

    • df.loc[[1,3],:]KeyError を発生させました。

    両方とも [1,3] で再インデックス付けされたフレームを返すようになりました。例:

    In [3]: df.loc[[1, 3]]
    Out[3]:
         0
    1    a
    3  NaN
    
    In [4]: df.loc[[1, 3], :]
    Out[4]:
         0
    1    a
    3  NaN
    

    これは、Panel を使用した多軸インデックス付けでも見られます。

    >>> p = pd.Panel(np.arange(2 * 3 * 4).reshape(2, 3, 4),
    ...              items=['ItemA', 'ItemB'],
    ...              major_axis=[1, 2, 3],
    ...              minor_axis=['A', 'B', 'C', 'D'])
    >>> p
    <class 'pandas.core.panel.Panel'>
    Dimensions: 2 (items) x 3 (major_axis) x 4 (minor_axis)
    Items axis: ItemA to ItemB
    Major_axis axis: 1 to 3
    Minor_axis axis: A to D
    

    以下のコードは、0.15.0 より前では KeyError を発生させました。

    In [5]:
    Out[5]:
       ItemA  ItemD
    1      3    NaN
    2      7    NaN
    3     11    NaN
    

    さらに、.loc は、リストライクなインデクサを持つ MultiIndex で値が見つからない場合に発生します。

    In [63]: s = pd.Series(np.arange(3, dtype='int64'),
       ....:               index=pd.MultiIndex.from_product([['A'],
       ....:                                                ['foo', 'bar', 'baz']],
       ....:                                                names=['one', 'two'])
       ....:               ).sort_index()
       ....: 
    
    In [64]: s
    Out[64]: 
    one  two
    A    bar    1
         baz    2
         foo    0
    Length: 3, dtype: int64
    
    In [65]: try:
       ....:     s.loc[['D']]
       ....: except KeyError as e:
       ....:     print("KeyError: " + str(e))
       ....: 
    KeyError: "['D'] not in index"
    
  • None への値の割り当ては、'空' の値を選択する際に dtype を考慮するようになりました (GH 7941)。

    以前は、数値コンテナで None を割り当てると、dtype がオブジェクトに変わるか (または呼び出しに応じてエラーが発生する)、現在は NaN が使用されます。

    In [66]: s = pd.Series([1., 2., 3.])
    
    In [67]: s.loc[0] = None
    
    In [68]: s
    Out[68]: 
    0    NaN
    1    2.0
    2    3.0
    Length: 3, dtype: float64
    

    NaT も同様に datetime コンテナで使用されるようになりました。

    オブジェクトコンテナの場合、None 値を保持するようになりました (以前はこれらは NaN 値に変換されていました)。

    In [69]: s = pd.Series(["a", "b", "c"])
    
    In [70]: s.loc[0] = None
    
    In [71]: s
    Out[71]: 
    0    None
    1       b
    2       c
    Length: 3, dtype: object
    

    NaN を挿入するには、明示的に np.nan を使用する必要があります。ドキュメントを参照してください。

  • 以前のバージョンでは、pandas オブジェクトをインプレースで更新しても、このオブジェクトへの他のPython参照には反映されませんでした。( GH 8511, GH 5104)

    In [72]: s = pd.Series([1, 2, 3])
    
    In [73]: s2 = s
    
    In [74]: s += 1.5
    

    v0.15.0 以前の動作

    # the original object
    In [5]: s
    Out[5]:
    0    2.5
    1    3.5
    2    4.5
    dtype: float64
    
    
    # a reference to the original object
    In [7]: s2
    Out[7]:
    0    1
    1    2
    2    3
    dtype: int64
    

    これが正しい動作です。

    # the original object
    In [75]: s
    Out[75]: 
    0    2.5
    1    3.5
    2    4.5
    Length: 3, dtype: float64
    
    # a reference to the original object
    In [76]: s2
    Out[76]: 
    0    2.5
    1    3.5
    2    4.5
    Length: 3, dtype: float64
    
  • read_csv および read_table の C ベースと Python エンジンの両方が、sep が空白文字でない限り、入力内の空行および空白文字で埋められた行を無視するようにしました。これは、キーワードパラメータ skip_blank_lines で制御できるAPI変更です。ドキュメントを参照してください (GH 4466)

  • UTC にローカライズされた時系列/インデックスは、Series/DataFrame に挿入されると、naive な datetime64[ns] に変換されるのではなく、object dtype として UTC タイムゾーンを保持します (GH 8411)。

  • 辞書からのDataFrame構築において、タイムゾーンが保持されなかったタイムゾーン付きの DatetimeIndex を渡す際のバグが修正されました (GH 7822)

    以前は、これによりタイムゾーンが失われましたが、現在はタイムゾーンが保持され、object dtype の列が生成されます。

    In [77]: i = pd.date_range('1/1/2011', periods=3, freq='10s', tz='US/Eastern')
    
    In [78]: i
    Out[78]: 
    DatetimeIndex(['2011-01-01 00:00:00-05:00', '2011-01-01 00:00:10-05:00',
                   '2011-01-01 00:00:20-05:00'],
                  dtype='datetime64[ns, US/Eastern]', freq='10s')
    
    In [79]: df = pd.DataFrame({'a': i})
    
    In [80]: df
    Out[80]: 
                              a
    0 2011-01-01 00:00:00-05:00
    1 2011-01-01 00:00:10-05:00
    2 2011-01-01 00:00:20-05:00
    
    [3 rows x 1 columns]
    
    In [81]: df.dtypes
    Out[81]: 
    a    datetime64[ns, US/Eastern]
    Length: 1, dtype: object
    

    以前は、これにより datetime64 dtype の列が生成されましたが、タイムゾーン情報はありませんでした。

    既存のデータフレームに df['a'] = i のように列を割り当てる動作は変更されていません(これはすでにタイムゾーン付きの object 列を返していました)。

  • stack() に複数のレベルを渡す際、すべてのレベル名またはすべてのレベル番号ではない場合、ValueError が発生するようになりました (GH 7660)。Reshaping by stacking and unstackingを参照してください。

  • df.to_hdf で 'fixed' フォーマットの場合、df に重複する列があると、結果のファイルが破損するため、ValueError が発生するようになりました (GH 7761)

  • SettingWithCopy の例外/警告(オプション mode.chained_assignment に応じて)は、連鎖割り当てを使用してスライスされた混合型 DataFrame の値設定時に発行されるようになりました。( GH 7845, GH 7950)

    In [1]: df = pd.DataFrame(np.arange(0, 9), columns=['count'])
    
    In [2]: df['group'] = 'b'
    
    In [3]: df.iloc[0:5]['group'] = 'a'
    /usr/local/bin/ipython:1: SettingWithCopyWarning:
    A value is trying to be set on a copy of a slice from a DataFrame.
    Try using .loc[row_indexer,col_indexer] = value instead
    
    See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
    
  • merge, DataFrame.merge, および ordered_merge は、left 引数と同じ型を返すようになりました (GH 7737)。

  • 以前は、混合型のフレームでの拡張は、dtype を保持する .append とは異なり動作していました (関連 GH 2578, GH 8176)

    In [82]: df = pd.DataFrame([[True, 1], [False, 2]],
       ....:                   columns=["female", "fitness"])
       ....: 
    
    In [83]: df
    Out[83]: 
       female  fitness
    0    True        1
    1   False        2
    
    [2 rows x 2 columns]
    
    In [84]: df.dtypes
    Out[84]: 
    female      bool
    fitness    int64
    Length: 2, dtype: object
    
    # dtypes are now preserved
    In [85]: df.loc[2] = df.loc[1]
    
    In [86]: df
    Out[86]: 
       female  fitness
    0    True        1
    1   False        2
    2   False        2
    
    [3 rows x 2 columns]
    
    In [87]: df.dtypes
    Out[87]: 
    female      bool
    fitness    int64
    Length: 2, dtype: object
    
  • Series.to_csv()path=None の場合に文字列を返すようになりました。これは DataFrame.to_csv() の動作と一致します (GH 8215)。

  • read_hdf は、存在しないファイルを渡された場合、IOError を発生させるようになりました。以前は、新しい空のファイルが作成され、KeyError が発生していました (GH 7715)。

  • DataFrame.info() は、出力の末尾に改行文字を表示するようになりました (GH 8114)

  • オブジェクトを連結しない場合、裸の Exception ではなく、ValueError が発生するようになりました。

  • マージエラーは、生の Exception ではなく、ValueError のサブクラスとなるようになりました (GH 8501)

  • DataFrame.plot および Series.plot のキーワードの順序が一貫するようになりました (GH 8037)

内部リファクタリング#

0.15.0 では、Index は内部的に ndarray のサブクラスではなく、他の pandas オブジェクトと同様に PandasObject のサブクラスになるようにリファクタリングされました。この変更により、新しいインデックス型のサブクラス化と作成が非常に容易になります。これは非常に限られたAPIへの影響しか持たない透過的な変更であるはずです。( GH 5080, GH 7439, GH 7796, GH 8024, GH 8367, GH 7997, GH 8522)

  • pandas バージョン < 0.15.0 の pickle をアンピックルするには、pickle.load ではなく pd.read_pickle を使用する必要がある場合があります。pickle docs を参照してください。

  • PeriodIndex でプロットする場合、matplotlib の内部軸は PeriodIndex ではなく Period の配列になります (これは DatetimeIndexdatetimes の配列を渡すのと同様です)。

  • MultiIndex は、真偽値テストに関して他の pandas オブジェクトと同様に例外を発生させるようになりました。こちらを参照してください (GH 7897)。

  • matplotlib の plot 関数で DatetimeIndex を直接プロットする場合、軸ラベルは日付形式ではなく整数 ( datetime64 の内部表現) としてフォーマットされるようになりました。更新: これは 0.15.1 で修正されました。こちらを参照してください。

非推奨#

  • Categoricallabels および levels 属性は非推奨となり、それぞれ codes および categories に改名されました。

  • pd.DataFrame.to_dictouttype 引数は非推奨となり、orient が推奨されます。( GH 7840)

  • convert_dummies メソッドは非推奨となり、get_dummies が推奨されます (GH 8140)

  • tz_localizeinfer_dst 引数は非推奨となり、DST 遷移をより柔軟に処理するために ambiguous が推奨されます。同じ動作を得るには、infer_dst=Trueambiguous='infer' に置き換えてください (GH 7943)。詳細についてはドキュメントを参照してください。

  • トップレベルの pd.value_range は非推奨となり、.describe() に置き換えられます (GH 8481)

  • Index のセット演算 +- は、特定のインデックス型に対する数値型演算のために提供するために非推奨となりました。+.union() または | に、-.difference() に置き換えられます。さらに、メソッド名 Index.diff() は非推奨となり、Index.difference() に置き換えられます (GH 8226)

    # +
    pd.Index(['a', 'b', 'c']) + pd.Index(['b', 'c', 'd'])
    
    # should be replaced by
    pd.Index(['a', 'b', 'c']).union(pd.Index(['b', 'c', 'd']))
    
    # -
    pd.Index(['a', 'b', 'c']) - pd.Index(['b', 'c', 'd'])
    
    # should be replaced by
    pd.Index(['a', 'b', 'c']).difference(pd.Index(['b', 'c', 'd']))
    
  • read_html()infer_types 引数は効果がなく、非推奨となりました (GH 7762, GH 7032)。

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

  • DataFrame.delevel メソッドを削除し、代わりに DataFrame.reset_index を推奨します。

機能強化#

Stataファイルのインポート/エクスポートの強化

  • to_stata で bool, uint8, uint16, uint32 データ型をサポートしました (GH 7097, GH 7365)

  • Stata ファイルのインポート時に変換オプションを追加しました (GH 8527)

  • DataFrame.to_stata および StataWriter は、固定幅文字列が244文字以下でなければならないdtaファイルに課せられる制限との互換性のために文字列の長さをチェックします。244文字を超える文字列を持つStata dtaファイルを書き込もうとすると、ValueError が発生します。( GH 7858)

  • read_stata および StataReader は、引数 convert_missingTrue に設定することで、欠損値情報を DataFrame にインポートできるようになりました。このオプションを使用すると、欠損値は StataMissingValue オブジェクトとして返され、欠損値を含む列は object データ型になります。( GH 8045)

プロット機能の強化

  • DataFrame.plotlayout キーワードを追加しました。これは (rows, columns) のタプルを渡すことができ、そのうちの1つを -1 にすると自動的に推測されます (GH 6667, GH 8071)。

  • DataFrame.plothistboxplot に複数の軸を渡せるようになりました (GH 5353, GH 6970, GH 7069)

  • DataFrame.plotkind='scatter'ccolormapcolorbar 引数をサポートしました (GH 7780)

  • DataFrame.plotkind='hist' を指定するとヒストグラムが描画されるようになりました (GH 7809)。ドキュメントを参照してください。

  • DataFrame.plotkind='box' を指定すると箱ひげ図が描画されるようになりました (GH 7998)。ドキュメントを参照してください。

その他

  • read_csvfloat_precision というキーワードパラメータが追加されました。これは、C エンジンが解析中に使用する浮動小数点コンバータを指定します。こちらを参照してください (GH 8002, GH 8044)。

  • Series オブジェクトに searchsorted メソッドを追加しました (GH 7447)

  • 混合型の DataFrame に対する describe() がより柔軟になりました。include/exclude 引数により、型ベースの列フィルタリングが可能になりました。ドキュメントを参照してください (GH 8164)。

    In [88]: df = pd.DataFrame({'catA': ['foo', 'foo', 'bar'] * 8,
       ....:                    'catB': ['a', 'b', 'c', 'd'] * 6,
       ....:                    'numC': np.arange(24),
       ....:                    'numD': np.arange(24.) + .5})
       ....: 
    
    In [89]: df.describe(include=["object"])
    Out[89]: 
           catA catB
    count    24   24
    unique    2    4
    top     foo    a
    freq     16    6
    
    [4 rows x 2 columns]
    
    In [90]: df.describe(include=["number", "object"], exclude=["float"])
    Out[90]: 
           catA catB       numC
    count    24   24  24.000000
    unique    2    4        NaN
    top     foo    a        NaN
    freq     16    6        NaN
    mean    NaN  NaN  11.500000
    std     NaN  NaN   7.071068
    min     NaN  NaN   0.000000
    25%     NaN  NaN   5.750000
    50%     NaN  NaN  11.500000
    75%     NaN  NaN  17.250000
    max     NaN  NaN  23.000000
    
    [11 rows x 3 columns]
    

    すべての列を要求するには、ショートハンド 'all' を使用できます。

    In [91]: df.describe(include='all')
    Out[91]: 
           catA catB       numC       numD
    count    24   24  24.000000  24.000000
    unique    2    4        NaN        NaN
    top     foo    a        NaN        NaN
    freq     16    6        NaN        NaN
    mean    NaN  NaN  11.500000  12.000000
    std     NaN  NaN   7.071068   7.071068
    min     NaN  NaN   0.000000   0.500000
    25%     NaN  NaN   5.750000   6.250000
    50%     NaN  NaN  11.500000  12.000000
    75%     NaN  NaN  17.250000  17.750000
    max     NaN  NaN  23.000000  23.500000
    
    [11 rows x 4 columns]
    

    これらの引数がない場合、describe は以前と同様に動作し、数値列のみ、または数値列がない場合はカテゴリ列のみを含みます。ドキュメントも参照してください。

  • pd.DataFrame.to_dictorient 引数に split オプションを追加しました。( GH 7840)

  • get_dummies メソッドが DataFrame で使用できるようになりました。デフォルトでは、カテゴリ列のみが 0 と 1 にエンコードされ、その他の列は変更されません。

    In [92]: df = pd.DataFrame({'A': ['a', 'b', 'a'], 'B': ['c', 'c', 'b'],
       ....:                 'C': [1, 2, 3]})
       ....: 
    
    In [93]: pd.get_dummies(df)
    Out[93]: 
       C    A_a    A_b    B_b    B_c
    0  1   True  False  False   True
    1  2  False   True  False   True
    2  3   True  False   True  False
    
    [3 rows x 5 columns]
    
  • PeriodIndexDatetimeIndex と同様に resolution をサポートします (GH 7708)

  • pandas.tseries.holiday は、追加の祝日と祝日を遵守する方法のサポートを追加しました (GH 7070)

  • pandas.tseries.holiday.Holiday は Python3 でオフセットのリストをサポートするようになりました (GH 7070)

  • pandas.tseries.holiday.Holidaydays_of_week パラメータをサポートするようになりました (GH 7070)

  • GroupBy.nth() は複数の nth 値を選択できるようになりました (GH 7910)

    In [94]: business_dates = pd.date_range(start='4/1/2014', end='6/30/2014', freq='B')
    
    In [95]: df = pd.DataFrame(1, index=business_dates, columns=['a', 'b'])
    
    # get the first, 4th, and last date index for each month
    In [96]: df.groupby([df.index.year, df.index.month]).nth([0, 3, -1])
    Out[96]: 
                a  b
    2014-04-01  1  1
    2014-04-04  1  1
    2014-04-30  1  1
    2014-05-01  1  1
    2014-05-06  1  1
    2014-05-30  1  1
    2014-06-02  1  1
    2014-06-05  1  1
    2014-06-30  1  1
    
    [9 rows x 2 columns]
    
  • Period および PeriodIndextimedelta ライクなものとの加算/減算をサポートします (GH 7966)

    Period の freq が D, H, T, S, L, U, N の場合、結果が同じ freq を持つことができる場合は Timedelta ライクなものを加算できます。それ以外の場合は、同じ offsets のみ加算できます。

    In [104]: idx = pd.period_range('2014-07-01 09:00', periods=5, freq='H')
    
    In [105]: idx
    Out[105]:
    PeriodIndex(['2014-07-01 09:00', '2014-07-01 10:00', '2014-07-01 11:00',
                 '2014-07-01 12:00', '2014-07-01 13:00'],
                dtype='period[H]')
    
    In [106]: idx + pd.offsets.Hour(2)
    Out[106]:
    PeriodIndex(['2014-07-01 11:00', '2014-07-01 12:00', '2014-07-01 13:00',
                 '2014-07-01 14:00', '2014-07-01 15:00'],
                dtype='period[H]')
    
    In [107]: idx + pd.Timedelta('120m')
    Out[107]:
    PeriodIndex(['2014-07-01 11:00', '2014-07-01 12:00', '2014-07-01 13:00',
                 '2014-07-01 14:00', '2014-07-01 15:00'],
                dtype='period[H]')
    
    In [108]: idx = pd.period_range('2014-07', periods=5, freq='M')
    
    In [109]: idx
    Out[109]: PeriodIndex(['2014-07', '2014-08', '2014-09', '2014-10', '2014-11'], dtype='period[M]')
    
    In [110]: idx + pd.offsets.MonthEnd(3)
    Out[110]: PeriodIndex(['2014-10', '2014-11', '2014-12', '2015-01', '2015-02'], dtype='period[M]')
    
  • バージョン >= 2.0 の openpyxl との実験的な互換性を追加しました。DataFrame.to_excel メソッドの engine キーワードは、openpyxl1openpyxl2 を認識するようになり、それぞれ明示的に openpyxl v1 と v2 を要求し、要求されたバージョンが利用できない場合は失敗します。openpyxl エンジンは、インストールされている openpyxl のバージョンを自動的に使用するメタエンジンになりました。( GH 7177)

  • DataFrame.fillna は、埋める値として DataFrame を受け入れるようになりました (GH 8377)

  • stack() に複数のレベルを渡す際、複数のレベル番号が渡されても動作するようになりました (GH 7660)。Reshaping by stacking and unstackingを参照してください。

  • set_names()set_labels()、および set_levels() メソッドは、MultiIndex の特定のレベルを変更するためのオプションの level キーワード引数を受け入れるようになりました。さらに、set_names() は、Index または MultiIndex の特定のレベルで操作する場合に、スカラ文字列値を受け入れるようになりました (GH 7792)

    In [97]: idx = pd.MultiIndex.from_product([['a'], range(3), list("pqr")],
       ....:                                  names=['foo', 'bar', 'baz'])
       ....: 
    
    In [98]: idx.set_names('qux', level=0)
    Out[98]: 
    MultiIndex([('a', 0, 'p'),
                ('a', 0, 'q'),
                ('a', 0, 'r'),
                ('a', 1, 'p'),
                ('a', 1, 'q'),
                ('a', 1, 'r'),
                ('a', 2, 'p'),
                ('a', 2, 'q'),
                ('a', 2, 'r')],
               names=['qux', 'bar', 'baz'])
    
    In [99]: idx.set_names(['qux', 'corge'], level=[0, 1])
    Out[99]: 
    MultiIndex([('a', 0, 'p'),
                ('a', 0, 'q'),
                ('a', 0, 'r'),
                ('a', 1, 'p'),
                ('a', 1, 'q'),
                ('a', 1, 'r'),
                ('a', 2, 'p'),
                ('a', 2, 'q'),
                ('a', 2, 'r')],
               names=['qux', 'corge', 'baz'])
    
    In [100]: idx.set_levels(['a', 'b', 'c'], level='bar')
    Out[100]: 
    MultiIndex([('a', 'a', 'p'),
                ('a', 'a', 'q'),
                ('a', 'a', 'r'),
                ('a', 'b', 'p'),
                ('a', 'b', 'q'),
                ('a', 'b', 'r'),
                ('a', 'c', 'p'),
                ('a', 'c', 'q'),
                ('a', 'c', 'r')],
               names=['foo', 'bar', 'baz'])
    
    In [101]: idx.set_levels([['a', 'b', 'c'], [1, 2, 3]], level=[1, 2])
    Out[101]: 
    MultiIndex([('a', 'a', 1),
                ('a', 'a', 2),
                ('a', 'a', 3),
                ('a', 'b', 1),
                ('a', 'b', 2),
                ('a', 'b', 3),
                ('a', 'c', 1),
                ('a', 'c', 2),
                ('a', 'c', 3)],
               names=['foo', 'bar', 'baz'])
    
  • Index.isin は、メンバシップテストに使用するインデックスレベルを指定する level 引数をサポートするようになりました (GH 7892, GH 7890)

    In [1]: idx = pd.MultiIndex.from_product([[0, 1], ['a', 'b', 'c']])
    
    In [2]: idx.values
    Out[2]: array([(0, 'a'), (0, 'b'), (0, 'c'), (1, 'a'), (1, 'b'), (1, 'c')], dtype=object)
    
    In [3]: idx.isin(['a', 'c', 'e'], level=1)
    Out[3]: array([ True, False,  True,  True, False,  True], dtype=bool)
    
  • Indexduplicateddrop_duplicates をサポートするようになりました。( GH 4060)

    In [102]: idx = pd.Index([1, 2, 3, 4, 1, 2])
    
    In [103]: idx
    Out[103]: Index([1, 2, 3, 4, 1, 2], dtype='int64')
    
    In [104]: idx.duplicated()
    Out[104]: array([False, False, False, False,  True,  True])
    
    In [105]: idx.drop_duplicates()
    Out[105]: Index([1, 2, 3, 4], dtype='int64')
    
  • pd.concatcopy=True 引数を追加し、完全なブロックの受け渡しを可能にしました (GH 8252)

  • Rデータフレームへの変換において、numpy 1.8以降のデータ型(bool_int_float_string_)のサポートを追加しました(GH 8400)。

パフォーマンス#

  • DatetimeIndex.__iter__のパフォーマンスが向上し、より高速なイテレーションが可能になりました(GH 7683)。

  • Periodの作成(およびPeriodIndexのsetitem)におけるパフォーマンスが向上しました(GH 5155)。

  • Series.transformの改善により、大幅なパフォーマンス向上を実現しました(改訂版)(GH 6496)。

  • 大きなファイルを読み込む際のStataReaderのパフォーマンスが向上しました(GH 8040GH 8073)。

  • 大きなファイルを書き込む際のStataWriterのパフォーマンスが向上しました(GH 8079)。

  • 複数キーのgroupbyにおけるパフォーマンスとメモリ使用量が改善されました(GH 8128)。

  • groupby .agg および .apply において、組み込みのmax/minがnumpy/cythonizedバージョンにマッピングされていなかった場合のパフォーマンスが改善されました(GH 7722)。

  • sqlへの書き込み(to_sql)のパフォーマンスが最大50%向上しました(GH 8208)。

  • ngroupsの値が大きい場合のgroupbyのパフォーマンスベンチマーク(GH 6787)。

  • CustomBusinessDayCustomBusinessMonthのパフォーマンスが向上しました(GH 8236)。

  • 日付時刻を含むマルチレベルインデックスの場合のMultiIndex.valuesのパフォーマンスが向上しました(GH 8543)。

バグ修正#

  • pivot_tableでmarginsとdict aggfuncを使用した場合のバグ(GH 8349)。

  • read_csvsqueeze=Trueがビューを返すバグ(GH 8217)。

  • 特定のケースでread_sqlにおけるテーブル名のチェックのバグ(GH 7826)。

  • DataFrame.groupbyで頻度が指定されている場合にGrouperがレベルを認識しないバグ(GH 7885)。

  • DataFrameをSQLテーブルに保存する際に、MultiIndexのdtypesが混在してしまうバグ(GH 8021)。

  • 浮動小数点数と整数オペランドのdtypeを持つSeriesの0除算のバグ(GH 7785)。

  • Series.astype("unicode")が値に対してunicodeを正しく呼び出さないバグ(GH 7758)。

  • 混在したdatetime64[ns]timedelta64[ns]のdtypeを持つDataFrame.as_matrix()のバグ(GH 7778)。

  • DatetimeIndexを選択する際にUTCタイムゾーン情報を保持しないHDFStore.select_column()のバグ(GH 7777)。

  • format='%Y%m%d'coerce=Trueが指定されたto_datetimeのバグ(以前は強制された時系列(NaTを含む)ではなくオブジェクト配列が返されていました)(GH 7930)。

  • DatetimeIndexPeriodIndexのインプレース加算と減算が通常の演算と異なる結果を引き起こすバグ(GH 6527)。

  • PeriodIndexPeriodIndexの加算および減算がTypeErrorを発生させるバグ(GH 7741)。

  • PeriodIndexデータでcombine_firstを使用するとTypeErrorが発生するバグ(GH 3367)。

  • インデクサーが欠落しているMultiIndexスライスでのバグ(GH 7866)。

  • 様々なエッジケースにおけるMultiIndexスライスでのバグ(GH 8132)。

  • 非スカラー型オブジェクトによるMultiIndexインデックス付けの退行(GH 7914)。

  • Timestampint64 dtypeの比較において==を使用した場合のバグ(GH 8058)。

  • DateOffsetを含むpickleが、内部でnormalize属性を参照する際にAttributeErrorを発生させる可能性があるバグ(GH 7748)。

  • Panelmajor_xsを使用し、copy=Falseが渡された場合のバグ(warningsが欠落しているため非推奨警告が失敗します)(GH 8152)。

  • ブロックとマネージャーアイテムを照合する際の曖昧さを避けるために、重複アイテムを持つpre-0.14.1コンテナのpickleデシリアライゼーションが失敗するバグ(ブロックが1つしかない場合は曖昧さはありません)(GH 7794)。

  • PeriodIndexSeriesに入れると、Periodsobject dtypeではなくint64 dtypeに変換されるバグ(GH 7932)。

  • whereを渡した際のHDFStoreイテレーションのバグ(GH 8014)。

  • 渡された非ソートキーで変換する際のDataFrameGroupby.transformのバグ(GH 8046GH 8430)。

  • 繰り返しの時系列線およびエリアプロットがValueErrorまたは誤った種類の結果となるバグ(GH 7733)。

  • datetime.date入力を伴うMultiIndexの推論のバグ(GH 7888)。

  • IndexErrorが発生してもデフォルト値が返されないgetのバグ(GH 7725)。

  • offsets.applyrollforwardrollbackがナノ秒をリセットする可能性があるバグ(GH 7697)。

  • Timestampdateutilのtzinfoを持っている場合、offsets.applyrollforwardrollbackAttributeErrorを発生させる可能性があるバグ(GH 7697)。

  • Float64Indexを持つMultiIndexフレームのソートのバグ(GH 8017)。

  • アライメントのためにDataFrameのrhsを持つpanel setitemの矛盾のバグ(GH 7763)。

  • is_superperiodis_subperiodSよりも高い頻度を処理できないバグ(GH 7760GH 7772GH 7803)。

  • 32ビットプラットフォームでSeries.shiftを使用した場合のバグ(GH 8129)。

  • PeriodIndex.uniqueがint64 np.ndarrayを返すバグ(GH 7540)。

  • 関数内で影響を与えない変更があるgroupby.applyのバグ(GH 8467)。

  • MultiIndexPeriodIndexまたはtzを含むDatetimeIndexが含まれているDataFrame.reset_indexValueErrorを発生させるバグ(GH 7746GH 7793)。

  • subplots=Trueを指定したDataFrame.plotが不要なマイナーなxticksとyticksを描画する可能性があるバグ(GH 7801)。

  • Stataのドキュメントと実装の差異により、117個のファイルで変数ラベルが読み込まれないStataReaderのバグ(GH 7816)。

  • StataReaderにおいて、基となる文字列のサイズに関わらず、文字列が常に244文字の固定幅に変換されるバグ(GH 7858)。

  • DataFrame.plotSeries.plotrotfontsizeキーワードを無視する可能性があるバグ(GH 7844)。

  • DatetimeIndex.value_countsがtzを保持しないバグ(GH 7735)。

  • PeriodIndex.value_countsInt64Indexを返すバグ(GH 7735)。

  • DataFrame.joinでインデックスに対して左結合を行い、複数のマッチがある場合のバグ(GH 5391)。

  • GroupBy.transform()のバグ。インデックスを保持しない変換を行ったintグループが誤って切り詰められていました(GH 7972)。

  • groupbyで、name属性のない呼び出し可能オブジェクトが誤ったパスをたどり、SeriesではなくDataFrameを生成するバグ(GH 7929)。

  • DataFrameのグループ化列が重複している場合のgroupbyのエラーメッセージのバグ(GH 7511)。

  • read_htmlのバグ。infer_types引数が、date-likesの強制的な型変換を誤って行いました(GH 7762GH 7032)。

  • 最初の項目を含まないようにインデックスがフィルタリングされたSeries.str.catのバグ(GH 7857)。

  • Timestampが文字列からnanosecondをパースできないバグ(GH 7878)。

  • Timestampで文字列オフセットとtzを指定すると結果が不正になるバグ(GH 7833)。

  • tslib.tz_converttslib.tz_convert_singleが異なる結果を返す可能性があるバグ(GH 7798)。

  • tzを持つ重複しないタイムスタンプのDatetimeIndex.intersectionIndexErrorを発生させるバグ(GH 7880)。

  • TimeOpsと非ユニークなインデックスのアライメントのバグ(GH 8363)。

  • GroupBy.filter()のバグ。高速パスと低速パスの違いにより、フィルタが有効に見えるが実際には無効な非スカラー値を返しました(GH 7870)。

  • date_range()/DatetimeIndex()のバグ。タイムゾーンが入力日付から推測されたにもかかわらず、DST境界を越えると誤った時刻が返されました(GH 7835GH 7901)。

  • to_excel()のバグ。正の無限大に負の記号が付加され、負の無限大には付加されていませんでした(GH 7949)。

  • エリアプロットがstacked=Trueの場合に誤ったalphaで凡例を描画するバグ(GH 8027)。

  • PeriodPeriodIndexnp.timedelta64の加算/減算が不正な内部表現になるバグ(GH 7740)。

  • オフセットまたは慣例のないHolidayのバグ(GH 7987)。

  • 列またはインデックスがMultiIndexの場合のDataFrame.to_latexの書式設定のバグ(GH 7982)。

  • 夏時間に関するDateOffsetのバグが予期しない結果を生み出す(GH 5175)。

  • DataFrame.shiftにおいて、空の列がnumpy 1.7でZeroDivisionErrorをスローするバグ(GH 8019)。

  • インストール時にhtml_encoding/*.htmlがインストールされず、一部のテストが正しく実行されないバグ(GH 7927)。

  • read_htmlのバグ。_readbytesオブジェクトがテストされていませんでした(GH 7927)。

  • DataFrame.stack()で列レベルの1つが日付型であった場合のバグ(GH 8039)。

  • DataFrameでnumpyスカラーをブロードキャストする際のバグ(GH 8116)。

  • 名前のないindexcolumnsで実行されたpivot_tableKeyErrorを発生させるバグ(GH 8103)。

  • DataFrame.plot(kind='scatter')が、cキーワードで色が指定されている場合に、異なる色で点と誤差棒を描画するバグ(GH 8081)。

  • Float64Indexiatatがテストされておらず、失敗していたバグ(GH 8092)。

  • DataFrame.boxplot()で複数の軸を生成する際に、y軸の制限が正しく設定されないバグ(GH 7528GH 5517)。

  • read_csvで、カスタムの行ターミネータまたはdelim_whitespace=Trueが指定された場合に、行コメントが正しく処理されないバグ(GH 8122)。

  • read_htmlで、空のテーブルがStopIterationを発生させるバグ(GH 7575)。

  • 同じdtypeブロックで列を設定する際のキャスティングのバグ(GH 7704)。

  • 元のグルーピングがタプルであった場合に、GroupByからグループにアクセスする際のバグ(GH 8121)。

  • 非整数インデックスで整数インデクサーを受け入れ、フォールバックする.atのバグ(GH 7814)。

  • kdeプロットとNaNsのバグ(GH 8182)。

  • GroupBy.countで、float32データ型のNaN値が除外されないバグ(GH 8169)。

  • スタック棒グラフとNaNsのバグ(GH 8175)。

  • 均等に分割できないオフセット(例:「7s」)でのリサンプルのバグ(GH 8371)。

  • 補間が必要な値がない場合に、limitキーワードを使用する補間メソッドのバグ(GH 7173)。

  • header=Falseの場合に、DataFrame.to_string()col_spaceが無視されるバグ(GH 8230)。

  • DatetimeIndex.asofが部分文字列に誤ってマッチし、間違った日付を返すバグ(GH 8245)。

  • プロットメソッドがグローバルなmatplotlib rcParamsを変更するバグ(GH 8242)。

  • DataFrame.__setitem__で、データフレームの列にスパース配列を設定するとエラーが発生するバグ(GH 8131)。

  • Dataframe.boxplot()が、列全体が空の場合に失敗するバグ(GH 8181)。

  • radviz可視化で変数が混乱するバグ(GH 8199)。

  • 補間が必要な値がない場合に、limitキーワードを使用する補間メソッドのバグ(GH 7173)。

  • header=Falseの場合に、DataFrame.to_string()col_spaceが無視されるバグ(GH 8230)。

  • 長い列データをクリップしてしまうto_clipboardのバグ(GH 8305)。

  • DataFrameの端末表示のバグ:max_column/max_rowsをゼロに設定しても、dfの端末幅/高さへの自動リサイズがトリガーされませんでした(GH 7180)。

  • OLSで「cluster」と「nw_lags」パラメータを使って実行した場合に、正しく機能しないがエラーもスローされないバグ(GH 5884)。

  • DataFrame.dropnaのバグ。subset引数に存在しない列を「最後の列」として解釈していました(GH 8303)。

  • 非単調で非ユニークなインデックスに対するIndex.intersectionのバグ(GH 8362)。

  • マスクされたシリーズの割り当てで、型が一致しないとアライメントが破綻するバグ(GH 8387)。

  • NDFrame.equalsがdtype=objectで偽陰性を出すバグ(GH 8437)。

  • インデクサーによる代入で、型の多様性によってアライメントが崩れるバグ(GH 8258)。

  • NDFrame.locインデックス付けのバグ。ターゲットがリスト/ndarrayの場合、行/列名が失われました(GH 6552)。

  • NDFrame.locインデックス付けの回帰。ターゲットが空のリスト/ndarrayの場合、行/列がFloat64Indexに変換されました(GH 7774)。

  • SeriesDataFrameによってインデックス付けされることを許可し、予期しない結果をもたらすバグ。このようなインデックス付けは許可されなくなりました(GH 8444)。

  • MultiIndexの列を持つDataFrameのアイテム代入で、右辺の列がアライメントされていないバグ(GH 7655)。

  • NaNを含むオブジェクト配列を比較する際にNumPyが生成するFutureWarningを抑制(GH 7065)。

  • DataFrame.eval()で、not演算子(~)のdtypeが正しくboolと推論されないバグ。

貢献者#

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

  • アーロン・シューマッハ +

  • アダム・グリーンホール

  • アンディ・ヘイデン

  • アンソニー・オブライエン +

  • アルテミー・コルチンスキー +

  • ベン・シラー +

  • ベネディクト・ザウアー

  • ベンジャミン・ティロー +

  • ボリス・ベルク +

  • クリス・レイノルズ +

  • クリス・ストーファー +

  • DSM

  • ダヴ・クラーク +

  • フラッグレッグス +

  • ジャーマン・ゴメス・ヘレーロ +

  • シャオミン・ヤン +

  • フアン・リー +

  • ヒョンテ・キム +

  • アイザック・スラビット +

  • ジェイコブ・シャアー

  • ジェイコブ・ワッサーマン +

  • ヤン・シュルツ

  • ジェフ・リーバック

  • Jeff Tratner

  • ジェシー・ファーンハム +

  • ジョー・ブラディッシュ +

  • ヨルグ・リッティンガー +

  • John W. O’Brien

  • Joris Van den Bossche

  • ケビン・シェパード

  • Kyle Meyer

  • マックス・チャン +

  • マイケル・ミューラー

  • マイケル・W・シャッツォウ +

  • Mike Kelly

  • モルタダ・メヒヤル

  • ネイサン・サンダース +

  • ネイサン・ティパンスキー +

  • ポール・マシュレル +

  • Phillip Cloud

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

  • レンゾ・ベルトッチ +

  • ロス・ペッチラー +

  • シャフル・ハミード +

  • シャシャンク・アガルワル +

  • ステファン・ホイヤー

  • Tom Augspurger

  • TomAugspurger

  • トニー・ロレンゾ +

  • ウェス・ターナー

  • ウィルフレッド・ヒューズ +

  • エフゲニー・グレチカ +

  • ヨシキ・バスケス・バエザ +

  • ベザード・ヌーリ +

  • ベンジャミン

  • ビョーネン +

  • ドロベル +

  • dsm054

  • ハンター・オーウェンズ +

  • immerrr

  • イシュワバッハー

  • jmorris0x0 +

  • jnmclarty +

  • jreback

  • クロヌオ +

  • レクシュアル

  • mcjcode +

  • mtrbean +

  • ワンズアンドゼロズ

  • ロックg

  • seth-p

  • sinhrks

  • サムベン +

  • スタールース +

  • スタス-sl +

  • ザットニート +

  • トム・アルコーン +

  • 不明

  • unutbu

  • ザックcp +