Pandas-2-2-中文文档-五十八-

Pandas 2.2 中文文档(五十八)

原文:pandas.pydata.org/docs/

版本 0.15.1(2014 年 11 月 9 日)

原文:pandas.pydata.org/docs/whatsnew/v0.15.1.html

这是从 0.15.0 版本中的一个小 bug 修复版本,包括少量 API 更改、几个新功能、增强和性能改进以及大量的 bug 修复。我们建议所有用户升级到此版本。

  • 增强

  • API 变更

  • Bug 修复

API 变更

  • s.dt.hour和其他.dt访问器现在将对缺失值返回np.nan(而不是以前的-1),(GH 8689)

    In [1]: s = pd.Series(pd.date_range("20130101", periods=5, freq="D"))
    
    In [2]: s.iloc[2] = np.nan
    
    In [3]: s
    Out[3]: 
    0   2013-01-01
    1   2013-01-02
    2          NaT
    3   2013-01-04
    4   2013-01-05
    Length: 5, dtype: datetime64[ns] 
    

    以前的行为:

    In [6]: s.dt.hour
    Out[6]:
    0    0
    1    0
    2   -1
    3    0
    4    0
    dtype: int64 
    

    当前行为:

    In [4]: s.dt.hour
    Out[4]: 
    0    0.0
    1    0.0
    2    NaN
    3    0.0
    4    0.0
    Length: 5, dtype: float64 
    
  • 带有as_index=Falsegroupby将不会向结果添加错误的额外列 (GH 8582):

    In [5]: np.random.seed(2718281)
    
    In [6]: df = pd.DataFrame(np.random.randint(0, 100, (10, 2)), columns=["jim", "joe"])
    
    In [7]: df.head()
    Out[7]: 
     jim  joe
    0   61   81
    1   96   49
    2   55   65
    3   72   51
    4   77   12
    
    [5 rows x 2 columns]
    
    In [8]: ts = pd.Series(5 * np.random.randint(0, 3, 10)) 
    

    以前的行为:

    In [4]: df.groupby(ts, as_index=False).max()
    Out[4]:
     NaN  jim  joe
    0    0   72   83
    1    5   77   84
    2   10   96   65 
    

    当前行为:

    In [4]: df.groupby(ts, as_index=False).max()
    Out[4]:
     jim  joe
    0   72   83
    1   77   84
    2   96   65 
    
  • 如果列名与分组器名称冲突,groupby将不会错误地排除列 (GH 8112):

    In [9]: df = pd.DataFrame({"jim": range(5), "joe": range(5, 10)})
    
    In [10]: df
    Out[10]: 
     jim  joe
    0    0    5
    1    1    6
    2    2    7
    3    3    8
    4    4    9
    
    [5 rows x 2 columns]
    
    In [11]: gr = df.groupby(df["jim"] < 2) 
    

    以前的行为(不包括输出的第一列):

    In [4]: gr.apply(sum)
    Out[4]:
     joe
    jim
    False   24
    True    11 
    

    当前行为:

    In [12]: gr.apply(sum)
    Out[12]: 
     jim  joe
    jim 
    False    9   24
    True     1   11
    
    [2 rows x 2 columns] 
    
  • 支持使用单调递减索引进行切片,即使startstop在索引中找不到 (GH 7860):

    In [13]: s = pd.Series(["a", "b", "c", "d"], [4, 3, 2, 1])
    
    In [14]: s
    Out[14]: 
    4    a
    3    b
    2    c
    1    d
    Length: 4, dtype: object 
    

    以前的行为:

    In [8]: s.loc[3.5:1.5]
    KeyError: 3.5 
    

    当前行为:

    In [15]: s.loc[3.5:1.5]
    Out[15]: 
    3    b
    2    c
    Length: 2, dtype: object 
    
  • io.data.Options已针对 Yahoo Options 页面格式的更改进行修复 (GH 8612), (GH 8741)

    注意

    由于 Yahoo 期权页面布局的更改,现在给定到期日期时,Options方法现在返回单个到期日期的数据。以前,方法返回所选月份的所有数据。

    monthyear参数已取消弃用,可以用于获取给定月份的所有期权数据。

    如果给定的到期日期无效,则返回给定日期后的下一个到期日期的数据。

    期权数据框现在以callsYYMMDDputsYYMMDD的形式保存在实例上。以前它们保存为callsMMYYputsMMYY。下一个到期日期保存为callsputs

    新功能:

    • 现在,过期参数可以是单个日期或包含日期的类似列表的对象。

    • 添加了一个新属性expiry_dates,返回所有可用的到期日期。

    当前行为:

    In [17]: from pandas.io.data import Options
    
    In [18]: aapl = Options('aapl', 'yahoo')
    
    In [19]: aapl.get_call_data().iloc[0:5, 0:1]
    Out[19]:
     Last
    Strike Expiry     Type Symbol
    80     2014-11-14 call AAPL141114C00080000  29.05
    84     2014-11-14 call AAPL141114C00084000  24.80
    85     2014-11-14 call AAPL141114C00085000  24.05
    86     2014-11-14 call AAPL141114C00086000  22.76
    87     2014-11-14 call AAPL141114C00087000  21.74
    
    In [20]: aapl.expiry_dates
    Out[20]:
    [datetime.date(2014, 11, 14),
     datetime.date(2014, 11, 22),
     datetime.date(2014, 11, 28),
     datetime.date(2014, 12, 5),
     datetime.date(2014, 12, 12),
     datetime.date(2014, 12, 20),
     datetime.date(2015, 1, 17),
     datetime.date(2015, 2, 20),
     datetime.date(2015, 4, 17),
     datetime.date(2015, 7, 17),
     datetime.date(2016, 1, 15),
     datetime.date(2017, 1, 20)]
    
    In [21]: aapl.get_near_stock_price(expiry=aapl.expiry_dates[0:3]).iloc[0:5, 0:1]
    Out[21]:
     Last
    Strike Expiry     Type Symbol
    109    2014-11-22 call AAPL141122C00109000  1.48
     2014-11-28 call AAPL141128C00109000  1.79
    110    2014-11-14 call AAPL141114C00110000  0.55
     2014-11-22 call AAPL141122C00110000  1.02
     2014-11-28 call AAPL141128C00110000  1.32 
    
  • pandas 现在还在 matplotlib 的单位注册表中注册了datetime64数据类型,以便将这些值作为日期时间绘制。这在导入 pandas 后激活。在先前的版本中,绘制datetime64值的数组将导致绘制整数值。要保持先前的行为,可以执行del matplotlib.units.registry[np.datetime64] (GH 8614)。

  • concat允许将更广泛的 pandas 对象的可迭代对象作为第一个参数传递 (GH 8645):

    In [16]: from collections import deque
    
    In [17]: df1 = pd.DataFrame([1, 2, 3])
    
    In [18]: df2 = pd.DataFrame([4, 5, 6]) 
    

    之前的行为:

    In [7]: pd.concat(deque((df1, df2)))
    TypeError: first argument must be a list-like of pandas objects, you passed an object of type "deque" 
    

    当前行为:

    In [19]: pd.concat(deque((df1, df2)))
    Out[19]: 
     0
    0  1
    1  2
    2  3
    0  4
    1  5
    2  6
    
    [6 rows x 1 columns] 
    
  • 使用占据基于级别大小的内存的 dtype 来表示 MultiIndex 标签。在之前的版本中,每个级别中每个元素的内存使用量是一个常量 8 字节。此外,在之前的版本中,报告的内存使用量是不正确的,因为它没有显示底层数据数组占用的内存。 (GH 8456)

    In [20]: dfi = pd.DataFrame(
     ....:    1, index=pd.MultiIndex.from_product([["a"], range(1000)]), columns=["A"]
     ....: )
     ....: 
    

    之前的行为:

    # this was underreported in prior versions
    In [1]: dfi.memory_usage(index=True)
    Out[1]:
    Index    8000 # took about 24008 bytes in < 0.15.1
    A        8000
    dtype: int64 
    

    当前行为:

    In [21]: dfi.memory_usage(index=True)
    Out[21]: 
    Index    44212
    A         8000
    Length: 2, dtype: int64 
    
  • 添加了 Index 属性 is_monotonic_increasingis_monotonic_decreasing (GH 8680).

  • 在导入 Stata 文件时添加了选择列的选项 (GH 7935)

  • 通过添加 + 来限定 DataFrame.info() 中的内存使用情况,如果它是一个下界 (GH 8578)

  • 在某些聚合情况下引发错误,例如处理 numeric_only 这样的参数时未处理 (GH 8592).

  • io.wb.download() 中增加了对 3 字符 ISO 和非标准国家代码的支持 (GH 8482)

  • 现在世界银行数据请求将根据一个 errors 参数进行警告/报错,以及一个硬编码的国家代码列表和世界银行的 JSON 响应。在之前的版本中,错误信息并未查看世界银行的 JSON 响应。在请求之前,有问题的输入仅仅被简单地丢弃。问题在于许多好的国家在硬编码方法中被截断了。现在所有国家都可以工作了,但一些不好的国家将会引发异常,因为一些边缘情况会破坏整个响应。 (GH 8482)

  • 添加了一个选项到 Series.str.split(),可以返回一个 DataFrame 而不是一个 Series (GH 8428)

  • 添加了一个选项到 df.info(null_counts=None|True|False) 来覆盖默认的显示选项,并强制显示空值计数 (GH 8701) ## 修复错误

  • 在反序列化 CustomBusinessDay 对象时出现错误 (GH 8591)

  • 在强制将 Categorical 转换为记录数组时出现错误,例如 df.to_records() (GH 8626)

  • 在使用 Series.to_frame() 时,Categorical 没有被正确创建的错误 (GH 8626)

  • 在传递 pd.Categorical 的情况下,Categoricalastype 强制转换中出现错误(现在会正确地引发 TypeError),(GH 8626)

  • 在使用 Seriesretbins=True 时,cut/qcut 出现错误 (GH 8589)

  • 在使用 to_sql 将分类列写入 SQL 数据库时出现错误 (GH 8624).

  • 修复了比较 Categorical 日期时引发错误的问题,当它与标量日期进行比较时(GH 8687)。

  • 在使用 .ilocCategorical 中选择时修复了一个错误(GH 8623)。

  • 在具有 Categorical 的 groupby-transform 中修复了一个错误(GH 8623)。

  • 在具有 Categorical 的重复/drop_duplicates 中修复了一个错误(GH 8623)。

  • Categorical 反映比较运算符时,若第一个参数是 numpy 数组标量(例如 np.int64),引发错误已修复(GH 8658)。

  • 在 Panel 使用类似列表的索引时修复了一个错误(GH 8710)。

  • options.mode.use_inf_as_null 为 True 时,修复了 DataFrame.dtypes 的兼容性问题(GH 8722)。

  • 修复了 read_csv 中,dialect 参数无法接受字符串的错误(GH 8703)。

  • 在使用空列表对 MultiIndex 级别进行切片时修复了一个错误(GH 8737)。

  • 在使用 Float/Index Index 和 numpy 数组进行数值索引操作时修复了一个错误(GH 8608)。

  • 修复了使用空索引器和不需要的 dtype 强制转换时的 setitem 错误(GH 8669)。

  • 在使用 ix/loc 进行分块设置时出现的错误(表现为整数样式的 dtype,例如 datetime64)已经修复(GH 8607)。

  • 在非唯一但单调索引上进行基于标签的索引时,修复了使用整数进行索引的错误(GH 8680)。

  • 修复了在 numpy 1.7 上使用 np.nan 对 Float64Index 进行索引时的错误(GH 8980)。

  • 修复了 MultiIndexshape 属性(GH 8609)。

  • GroupBy 中出现的名称冲突问题已修复,此问题会导致 grouper 和列之间的名称冲突破坏 groupby 操作(GH 7115GH 8112)。

  • 修复了绘制列 y 并指定标签时改变原始 DataFrame 索引名称的错误(GH 8494)。

  • 修复了使用 matplotlib 直接绘制 DatetimeIndex 时的回归问题(GH 8614)。

  • 修复了在 date_range 中,部分指定日期会包含当前日期的错误(GH 6961)。

  • 修复了使用索引器对具有混合 dtype 的 Panel4d 进行设置为标量值时失败的错误(GH 8702)。

  • 如果传递的符号中有一个无效,则DataReader将失败的错误。现在为有效符号返回数据,对于无效符号返回 np.nan(GH 8494

  • get_quote_yahoo中的错误,不允许非浮点返回值(GH 5229)。 ## 贡献者

总共有 23 人为此版本贡献了补丁。名字后面带有“+”的人第一次贡献了补丁。

  • Aaron Staple +

  • Andrew Rosenfeld

  • Anton I. Sipos

  • Artemy Kolchinsky

  • Bill Letson +

  • Dave Hughes +

  • David Stephens

  • Guillaume Horel +

  • Jeff Reback

  • Joris Van den Bossche

  • Kevin Sheppard

  • Nick Stahl +

  • Sanghee Kim +

  • Stephan Hoyer

  • Tom Augspurger

  • TomAugspurger

  • 王爱勇 +

  • behzad nouri

  • immerrr

  • jnmclarty

  • jreback

  • pallav-fdsi +

  • unutbu ## API 更改

  • s.dt.hour和其他.dt访问器现在将对缺失值返回np.nan(而不是以前的-1),(GH 8689

    In [1]: s = pd.Series(pd.date_range("20130101", periods=5, freq="D"))
    
    In [2]: s.iloc[2] = np.nan
    
    In [3]: s
    Out[3]: 
    0   2013-01-01
    1   2013-01-02
    2          NaT
    3   2013-01-04
    4   2013-01-05
    Length: 5, dtype: datetime64[ns] 
    

    以前的行为:

    In [6]: s.dt.hour
    Out[6]:
    0    0
    1    0
    2   -1
    3    0
    4    0
    dtype: int64 
    

    当前行为:

    In [4]: s.dt.hour
    Out[4]: 
    0    0.0
    1    0.0
    2    NaN
    3    0.0
    4    0.0
    Length: 5, dtype: float64 
    
  • groupbyas_index=False不会向结果添加错误的额外列(GH 8582):

    In [5]: np.random.seed(2718281)
    
    In [6]: df = pd.DataFrame(np.random.randint(0, 100, (10, 2)), columns=["jim", "joe"])
    
    In [7]: df.head()
    Out[7]: 
     jim  joe
    0   61   81
    1   96   49
    2   55   65
    3   72   51
    4   77   12
    
    [5 rows x 2 columns]
    
    In [8]: ts = pd.Series(5 * np.random.randint(0, 3, 10)) 
    

    以前的行为:

    In [4]: df.groupby(ts, as_index=False).max()
    Out[4]:
     NaN  jim  joe
    0    0   72   83
    1    5   77   84
    2   10   96   65 
    

    当前行为:

    In [4]: df.groupby(ts, as_index=False).max()
    Out[4]:
     jim  joe
    0   72   83
    1   77   84
    2   96   65 
    
  • 如果列名与分组器名称冲突,groupby不会错误地排除列(GH 8112):

    In [9]: df = pd.DataFrame({"jim": range(5), "joe": range(5, 10)})
    
    In [10]: df
    Out[10]: 
     jim  joe
    0    0    5
    1    1    6
    2    2    7
    3    3    8
    4    4    9
    
    [5 rows x 2 columns]
    
    In [11]: gr = df.groupby(df["jim"] < 2) 
    

    以前的行为(从输出中排除第一列):

    In [4]: gr.apply(sum)
    Out[4]:
     joe
    jim
    False   24
    True    11 
    

    当前行为:

    In [12]: gr.apply(sum)
    Out[12]: 
     jim  joe
    jim 
    False    9   24
    True     1   11
    
    [2 rows x 2 columns] 
    
  • 支持使用单调递减索引进行切片,即使startstop在索引中找不到(GH 7860):

    In [13]: s = pd.Series(["a", "b", "c", "d"], [4, 3, 2, 1])
    
    In [14]: s
    Out[14]: 
    4    a
    3    b
    2    c
    1    d
    Length: 4, dtype: object 
    

    以前的行为:

    In [8]: s.loc[3.5:1.5]
    KeyError: 3.5 
    

    当前行为:

    In [15]: s.loc[3.5:1.5]
    Out[15]: 
    3    b
    2    c
    Length: 2, dtype: object 
    
  • io.data.Options已针对 Yahoo Options 页面格式的更改进行修复(GH 8612),(GH 8741

    注意

    由于 Yahoo 期权页面布局的更改,当给定到期日期时,Options方法现在返回单个到期日期的数据。以前,方法返回所选月份的所有数据。

    monthyear参数已取消弃用,可用于获取给定月份的所有期权数据。

    如果给定了无效的到期日期,则返回给定日期后的下一个到期日期的数据。

    期权数据框现在保存在实例上,命名为callsYYMMDDputsYYMMDD。以前它们保存为callsMMYYputsMMYY。下一个到期日期保存为callsputs

    新功能:

    • 到期参数现在可以是单个日期或包含日期的类似列表对象。

    • 添加了一个新属性expiry_dates,返回所有可用的到期日期。

    当前行为:

    In [17]: from pandas.io.data import Options
    
    In [18]: aapl = Options('aapl', 'yahoo')
    
    In [19]: aapl.get_call_data().iloc[0:5, 0:1]
    Out[19]:
     Last
    Strike Expiry     Type Symbol
    80     2014-11-14 call AAPL141114C00080000  29.05
    84     2014-11-14 call AAPL141114C00084000  24.80
    85     2014-11-14 call AAPL141114C00085000  24.05
    86     2014-11-14 call AAPL141114C00086000  22.76
    87     2014-11-14 call AAPL141114C00087000  21.74
    
    In [20]: aapl.expiry_dates
    Out[20]:
    [datetime.date(2014, 11, 14),
     datetime.date(2014, 11, 22),
     datetime.date(2014, 11, 28),
     datetime.date(2014, 12, 5),
     datetime.date(2014, 12, 12),
     datetime.date(2014, 12, 20),
     datetime.date(2015, 1, 17),
     datetime.date(2015, 2, 20),
     datetime.date(2015, 4, 17),
     datetime.date(2015, 7, 17),
     datetime.date(2016, 1, 15),
     datetime.date(2017, 1, 20)]
    
    In [21]: aapl.get_near_stock_price(expiry=aapl.expiry_dates[0:3]).iloc[0:5, 0:1]
    Out[21]:
     Last
    Strike Expiry     Type Symbol
    109    2014-11-22 call AAPL141122C00109000  1.48
     2014-11-28 call AAPL141128C00109000  1.79
    110    2014-11-14 call AAPL141114C00110000  0.55
     2014-11-22 call AAPL141122C00110000  1.02
     2014-11-28 call AAPL141128C00110000  1.32 
    
  • pandas 现在还在 matplotlib 的单位注册表中注册了datetime64 dtype,以便绘制这样的值作为日期时间。这在导入 pandas 后激活。在以前的版本中,绘制datetime64值数组将导致绘制整数值。要保持以前的行为,可以执行del matplotlib.units.registry[np.datetime64]GH 8614)。

增强功能

  • concat允许传递更广泛的 pandas 对象的可迭代作为第一个参数(GH 8645):

    In [16]: from collections import deque
    
    In [17]: df1 = pd.DataFrame([1, 2, 3])
    
    In [18]: df2 = pd.DataFrame([4, 5, 6]) 
    

    先前行为:

    In [7]: pd.concat(deque((df1, df2)))
    TypeError: first argument must be a list-like of pandas objects, you passed an object of type "deque" 
    

    当前行为:

    In [19]: pd.concat(deque((df1, df2)))
    Out[19]: 
     0
    0  1
    1  2
    2  3
    0  4
    1  5
    2  6
    
    [6 rows x 1 columns] 
    
  • 使用一种利用基于级别大小的内存的 dtype 来表示MultiIndex标签。在之前的版本中,每个级别中的每个元素的内存使用量是一个恒定的 8 字节。此外,在之前的版本中,报告的内存使用量是不正确的,因为它没有显示底层数据数组占用的内存使用量。(GH 8456)

    In [20]: dfi = pd.DataFrame(
     ....:    1, index=pd.MultiIndex.from_product([["a"], range(1000)]), columns=["A"]
     ....: )
     ....: 
    

    先前行为:

    # this was underreported in prior versions
    In [1]: dfi.memory_usage(index=True)
    Out[1]:
    Index    8000 # took about 24008 bytes in < 0.15.1
    A        8000
    dtype: int64 
    

    当前行为:

    In [21]: dfi.memory_usage(index=True)
    Out[21]: 
    Index    44212
    A         8000
    Length: 2, dtype: int64 
    
  • 添加了 Index 属性is_monotonic_increasingis_monotonic_decreasingGH 8680

  • 在导入 Stata 文件时添加了选择列的选项(GH 7935

  • DataFrame.info()中通过添加+来限定内存使用量,如果是下限的话(GH 8578

  • 在某些聚合情况下引发错误,例如未处理numeric_only等参数(GH 8592

  • io.wb.download()中添加了对 3 字符 ISO 和非标准国家代码的支持(GH 8482

  • 现在世界银行数据请求将根据errors参数发出警告/引发异常,以及硬编码的国家代码列表和世界银行的 JSON 响应。在之前的版本中,错误消息没有查看世界银行的 JSON 响应。在请求之前,会简单地删除引起问题的输入。问题在于许多好的国家在硬编码方法中被裁剪。现在所有国家都可以使用,但一些不好的国家会引发异常,因为一些边缘情况会破坏整个响应。(GH 8482)

  • 添加了选项Series.str.split(),可以返回DataFrame而不是SeriesGH 8428

  • 添加了选项df.info(null_counts=None|True|False),以覆盖默认显示选项并强制显示空值计数(GH 8701

Bug 修复

  • 修复了CustomBusinessDay对象反序列化时的错误(GH 8591

  • 修复了将Categorical强制转换为记录数组的错误,例如df.to_records()GH 8626

  • 使用Series.to_frame()不正确创建分类数据的错误(GH 8626

  • 在传递pd.CategoricalCategorical的 astype 强制转换中存在错误(现在会正确地引发TypeError),(GH 8626

  • 当使用Seriesretbins=True时,使用cut/qcut存在错误(GH 8589

  • 使用to_sql将分类列写入 SQL 数据库存在错误(GH 8624)。

  • 当与标量日期时间进行比较时,比较Categorical日期时间时存在错误(GH 8687

  • 使用.ilocCategorical中选择存在错误(GH 8623

  • 使用分类数据进行 groupby-transform 存在错误(GH 8623

  • 使用分类数据时重复/删除重复项存在错误(GH 8623

  • 在反映比较运算符的Categorical中存在错误,如果第一个参数是 numpy 数组标量(例如 np.int64)(GH 8658

  • 对于类似列表的面板索引存在漏洞(GH 8710

  • options.mode.use_inf_as_null为 True 时,DataFrame.dtypes存在兼容性问题(GH 8722

  • read_csv中,dialect参数不接受字符串的错误(GH 8703

  • 使用空列表对多级索引级别进行切片存在错误(GH 8737

  • 在使用 Float/Index 索引的数值索引操作中,存在与 numpy 数组的 add/sub 的错误(GH 8608

  • 在空索引器的 setitem 中存在错误,并且不希望转换 dtype(GH 8669

  • 在 ix/loc 块拆分中存在错误(使用整数样式 dtype,例如 datetime64)(GH 8607

  • 当使用整数进行基于标签的索引但索引中不存在的非唯一但单调索引时存在错误(GH 8680)。

  • 当使用numpy 1.7中的np.nanFloat64Index进行索引时存在错误(GH 8980)。

  • 修复了对MultiIndexshape属性的错误(GH 8609

  • GroupBy中,分组器和列之间存在名称冲突将中断groupby操作的错误(GH 7115GH 8112

  • 修复了绘制列y并指定标签会改变原始 DataFrame 索引名称的错误(GH 8494

  • 修复了在使用 matplotlib 直接绘制 DatetimeIndex 时的回归问题(GH 8614)。

  • 修复了date_range中部分指定日期会包含当前日期的问题(GH 6961

  • 修复了将索引器设置为混合 dtype Panel4d的标量值时失败的 bug(GH 8702

  • 修复了如果传递的符号之一无效,DataReader会失败的 bug。现在对于有效符号返回数据,对于无效符号返回 np.nan(GH 8494

  • 修复了get_quote_yahoo中不允许非浮点返回值的 bug(GH 5229)。

贡献者

总共有 23 人为这个版本贡献了补丁。名字后面带有“+”的人第一次贡献了补丁。

  • Aaron Staple +

  • Andrew Rosenfeld

  • Anton I. Sipos

  • Artemy Kolchinsky

  • Bill Letson +

  • Dave Hughes +

  • David Stephens

  • Guillaume Horel +

  • Jeff Reback

  • Joris Van den Bossche

  • Kevin Sheppard

  • Nick Stahl +

  • Sanghee Kim +

  • Stephan Hoyer

  • Tom Augspurger

  • TomAugspurger

  • 王爱勇 +

  • behzad nouri

  • immerrr

  • jnmclarty

  • jreback

  • pallav-fdsi +

  • unutbu

版本 0.15.0(2014 年 10 月 18 日)

原文:pandas.pydata.org/docs/whatsnew/v0.15.0.html

这是从 0.14.1 版本的一个重大发布,包括少量 API 更改、几个新功能、增强功能和性能改进,以及大量的错误修复。我们建议所有用户升级到这个版本。

警告

pandas >= 0.15.0 将不再支持与 NumPy 版本 < 1.7.0 兼容。如果您想使用最新版本的 pandas,请升级到 NumPy >= 1.7.0 (GH 7711)

  • 亮点包括:

    • Categorical 类型被整合为第一类 pandas 类型,详见这里

    • 新的标量类型Timedelta,以及新的索引类型TimedeltaIndex,详见这里

    • 为 Series 新增了日期时间属性访问器.dt,详见日期时间属性

    • 新的 DataFrame 默认显示df.info()以包括内存使用情况,详见内存使用情况

    • read_csv现在默认情况下在解析时会忽略空行,详见这里

    • 在集合操作中使用索引的 API 更改,详见这里

    • 时区处理方面的增强功能,详见这里

    • 对滚动和扩展动量函数进行了许多改进,详见这里

    • Index类的内部重构为不再是子类ndarray,详见内部重构

    • 不再支持PyTables低于版本 3.0.0,以及numexpr低于版本 2.1 (GH 7990)

    • 将索引文档拆分为索引和选择数据和 MultiIndex / 高级索引

    • 将字符串方法文档拆分为处理文本数据

  • 在更新之前,请查看 API 更改和弃用

  • 其他增强功能

  • 性能改进

  • 错误修复

警告

在 0.15.0 版本中,Index 在内部已经重构,不再是子类ndarray,而是子类PandasObject,类似于其他 pandas 对象。这个改变使得非常容易进行子类化和创建新的索引类型。这应该是一个透明的改变,只有非常有限的 API 影响(参见内部重构)

警告

Categorical中的重构改变了两个参数构造函数从“codes/labels 和 levels”到“values 和 levels(现在称为‘categories’)”。这可能导致一些微妙的错误。如果您直接使用Categorical,请在更新到此 pandas 版本之前审查您的代码,并将其更改为使用from_codes()构造函数。在这里查看更多关于Categorical的信息(#whatsnew-0150-cat)

新功能

Series/DataFrame 中的 Categoricals

Categorical现在可以包含在SeriesDataFrames中,并获得了新的操作方法。感谢 Jan Schulz 为此 API/实现做出的贡献。(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_aggpandas.core.factor_agg 已移除。作为替代方案,构建一个数据框并使用 df.groupby(<group>).agg(<func>)

  • 不再支持向Categorical构造函数提供“codes/labels 和 levels”。现在将两个参数提供给构造函数解释为“values 和 levels(现在称为‘categories’)”。请修改您的代码以使用from_codes()构造函数。

  • Categorical.labels 属性已更名为 Categorical.codes,且只读。如果您想要操作编码,请使用 Categoricals 的 API 方法之一。

  • Categorical.levels属性更名为Categorical.categories。### TimedeltaIndex/scalar

我们引入了一个新的标量类型Timedelta,它是datetime.timedelta的子类,并且行为类似,但允许与np.timedelta64类型兼容,以及一系列自定义表示、解析和属性。这种类型与Timestamp处理datetimes的方式非常相似。它是类型的一个很好的 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返回hoursminutesseconds之间组合的总秒数。相比之下,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 版本更新

警告

在 0.15.0 之前,pd.to_timedelta会为类似列表/Series 的输入返回一个Series,对于标量输入会返回一个np.timedelta64。现在将为类似列表的输入返回一个TimedeltaIndex,对于 Series 输入返回一个Series,对于标量输入返回一个Timedelta

pd.to_timedelta的参数现在是(arg,unit='ns',box=True,coerce=False),之前是(arg,box=True,unit='ns'),因为这样更合乎逻辑。

构建一个标量

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')] 
  • Series的迭代,例如list(Series(...))timedelta64[ns]在 v0.15.0 之前会为每个元素返回np.timedelta64。现在将包装在Timedelta中。### 内存使用

实现了查找 DataFrame 内存使用的方法。更多信息请参阅 FAQ。(GH 6852)。

新的显示选项 display.memory_usage(请参阅选项和设置)设置 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), datetime64ns, float64(1), int64(1), object(1), timedelta64ns
memory usage: 288.2+ KB 

此外 memory_usage() 是一个 dataframe 对象的可用方法,它返回每列的内存使用情况。

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 访问器

`Series` 已经增加了一个访问器,以简洁地返回系列的日期时间属性,如果它是一个类似于日期时间/周期的系列。([GH 7207](https://github.com/pandas-dev/pandas/issues/7207))这将返回一个 Series,索引类似于现有的 Series。请参阅文档

```py
# 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] 

您可以轻松地生成 tz-aware 转换:

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 访问器适用于期间和时间增量 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] 
```  ### 时区处理改进

+   `tz_localize(None)` 适用于 tz-aware `Timestamp` 和 `DatetimeIndex`,现在删除持有本地时间的时区,以前会导致 `Exception` 或 `TypeError`([GH 7812](https://github.com/pandas-dev/pandas/issues/7812))

    ```py
    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_localize` 现在接受 `ambiguous` 关键字,允许传递一个指示日期是否属于夏令时的布尔数组,将过渡时间设置为 NaT 的 ‘NaT’,用于推断 DST/非 DST 的 ‘infer’,和 ‘raise’(默认)用于引发 `AmbiguousTimeError`。([GH 7943](https://github.com/pandas-dev/pandas/issues/7943))有关更多详细信息,请参阅文档。

+   `DataFrame.tz_localize` 和 `DataFrame.tz_convert` 现在接受可选的 `level` 参数,用于本地化多级索引的特定级别([GH 7846](https://github.com/pandas-dev/pandas/issues/7846))

+   `Timestamp.tz_localize` 和 `Timestamp.tz_convert` 现在在错误情况下引发 `TypeError`,而不是 `Exception`([GH 8025](https://github.com/pandas-dev/pandas/issues/8025))

+   插入到 Series/DataFrame 中的时序/索引在本地化为 UTC 时将保留 UTC 时区(而不是作为 `object` dtype 的幼稚 `datetime64[ns]`)([GH 8411](https://github.com/pandas-dev/pandas/issues/8411))

+   `Timestamp.__repr__` 显示 `dateutil.tz.tzoffset` 信息([GH 7907](https://github.com/pandas-dev/pandas/issues/7907))  ### 滚动/扩展时刻改进

+   当 `len(arg) < min_periods <= window` 时,`rolling_min()`、`rolling_max()`、`rolling_cov()` 和 `rolling_corr()` 现在返回所有 `NaN` 的对象,而不是引发异常。(这使得所有滚动函数在这方面的行为一致)。([GH 7766](https://github.com/pandas-dev/pandas/issues/7766))

    在 0.15.0 之前

    ```py
    In [57]: s = pd.Series([10, 11, 12, 13]) 
    ```

    ```py
    In [15]: pd.rolling_min(s, window=10, min_periods=5)
    ValueError: min_periods (5) must be <= window (4) 
    ```

    新行为

    ```py
    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](https://github.com/pandas-dev/pandas/issues/7925), [GH 8269](https://github.com/pandas-dev/pandas/issues/8269))

    先前的行为(注意最终值为`NaN`):

    ```py
    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])`):

    ```py
    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](https://github.com/pandas-dev/pandas/issues/7618))

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

    0.15.0 之前的行为:

    ```py
    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 
    ```

    新行为

    ```py
    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](https://github.com/pandas-dev/pandas/issues/7925))

+   向`expanding_cov()`和`rolling_cov()`添加了可选的`ddof`参数。默认值为`1`与向后兼容。([GH 8279](https://github.com/pandas-dev/pandas/issues/8279))

+   讲解了`expanding_var()`、`expanding_std()`、`rolling_var()`和`rolling_std()`中的`ddof`参数。这些函数支持`ddof`参数(默认值为`1`)以前未记录。([GH 8064](https://github.com/pandas-dev/pandas/issues/8064))

+   `ewma()`、`ewmstd()`、`ewmvol()`、`ewmvar()`、`ewmcov()`和`ewmcorr()`现在以与`rolling_*()`和`expanding_*()`函数相同的方式解释`min_periods`:如果(在这种情况下是扩展)窗口不包含至少`min_periods`个值,则给定的结果条目将为`NaN`。以前的行为是从第一个非`NaN`值开始将`min_periods`条目设置为`NaN`。([GH 7977](https://github.com/pandas-dev/pandas/issues/7977))

    先前的行为(注意值从索引`2`开始,这是索引`0`(第一个非空值的索引)之后的`min_periods`):

    ```py
    In [59]: s  = pd.Series([1, None, None, None, 2, 3]) 
    ```

    ```py
    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`开始,第 2 个(因为`min_periods=2`)非空值的位置):

    ```py
    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()` 现在具有可选的 `adjust` 参数,就像 `ewma()` 一样,影响权重的计算方式。`adjust` 的默认值为 `True`,与旧版本兼容。详见指数加权矩函数了解详情。([GH 7911](https://github.com/pandas-dev/pandas/issues/7911))

+   `ewma()`、`ewmstd()`、`ewmvol()`、`ewmvar()`、`ewmcov()` 和 `ewmcorr()` 现在具有可选的 `ignore_na` 参数。当 `ignore_na=False`(默认值)时,在权重计算中将考虑缺失值。当 `ignore_na=True`(重现早于 0.15.0 版本的行为)时,在权重计算中将忽略缺失值。([GH 7543](https://github.com/pandas-dev/pandas/issues/7543))

    ```py
    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` 的 DataFrame 的情况,其中行为不变)([GH 7542](https://github.com/pandas-dev/pandas/issues/7542))

+   `rolling_count()` 和 `expanding_*()` 函数中的错误,在零长度数据上不必要地生成错误消息 ([GH 8056](https://github.com/pandas-dev/pandas/issues/8056))

+   `rolling_apply()` 和 `expanding_apply()` 中的错误,将 `min_periods=0` 解释为 `min_periods=1` ([GH 8080](https://github.com/pandas-dev/pandas/issues/8080))

+   `expanding_std()` 和 `expanding_var()` 中的错误,对于单个值生成令人困惑的错误消息 ([GH 7900](https://github.com/pandas-dev/pandas/issues/7900))

+   `rolling_std()` 和 `rolling_var()` 中的错误,对于单个值生成 `0` 而不是 `NaN` ([GH 7900](https://github.com/pandas-dev/pandas/issues/7900))

+   当 `bias=False`(默认值)时,`ewmstd()`、`ewmvol()`、`ewmvar()` 和 `ewmcov()` 计算去偏因子时的错误。之前使用了错误的常数因子,基于 `adjust=True`、`ignore_na=True` 和无限数量的观测。现在,对于每个条目使用不同的因子,基于实际权重(类似于通常的 `N/(N-1)` 因子)。特别地,当 `bias=False` 时,对于单个点,返回 `NaN` 值,而以前返回 (近似) `0` 值。

    例如,考虑 `ewmvar(..., bias=False)` 的以下早于 0.15.0 版本的结果,以及相应的去偏因子:

    ```py
    In [60]: s = pd.Series([1., 2., 0., 4.]) 
    ```

    ```py
    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 结果的 `NaN` 条目 `0`,并且校准因子逐渐减少(向 1.25 靠拢):

    ```py
    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](https://github.com/pandas-dev/pandas/issues/7912))。### SQL IO 模块的改进

+   为 `to_sql` 函数添加了一个 `chunksize` 参数的支持。这允许 DataFrame 被分块写入,避免了数据包大小溢出错误([GH 8062](https://github.com/pandas-dev/pandas/issues/8062))。

+   为 `read_sql` 函数添加了一个 `chunksize` 参数的支持。指定此参数将返回查询结果的一个迭代器,以便逐块获取数据([GH 2908](https://github.com/pandas-dev/pandas/issues/2908))。

+   为 `to_sql` 添加了写入 `datetime.date` 和 `datetime.time` 对象列的支持([GH 6932](https://github.com/pandas-dev/pandas/issues/6932))。

+   为 `read_sql_table` 和 `to_sql` 添加了支持指定 `schema` 来读取/写入的功能([GH 7441](https://github.com/pandas-dev/pandas/issues/7441), [GH 7952](https://github.com/pandas-dev/pandas/issues/7952))。例如:

    ```py
    df.to_sql('table', engine, schema='other_schema')  # noqa F821
    pd.read_sql_table('table', engine, schema='other_schema')  # noqa F821 
    ```

+   为 `to_sql` 添加了写入 `NaN` 值的支持([GH 2754](https://github.com/pandas-dev/pandas/issues/2754))。

+   为所有数据库类型的 `to_sql` 添加了写入 datetime64 列的支持([GH 7103](https://github.com/pandas-dev/pandas/issues/7103))。## 向后不兼容的 API 更改

### 重大变更

与 `Categorical` 相关的 API 更改(更多详情请见这里):

+   `Categorical` 构造函数的两个参数从“codes/labels 和 levels”更改为“values 和 levels(现在称为‘categories’)”。这可能导致一些微妙的错误。如果直接使用 `Categorical`,请通过更改为使用 `from_codes()` 构造函数来审查您的代码。

    类似于旧版本(0.15.0 之前)的函数调用:

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

    必须适应以下以保持相同的行为:

    ```py
    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`,对于标量输入返回一个 `np.timedelta64`。现在,对于类似列表的输入,将返回一个 `TimedeltaIndex`,对于序列输入,将返回一个 `Series`,对于标量输入,将返回一个 `Timedelta`。

关于滚动和扩展函数的 API 更改,请参阅上述详细概述(#whatsnew-0150-roll)。

其他值得注意的 API 更改:

+   当使用 `.loc` 和类似列表的索引器进行索引时,如果找不到值,则保持一致性。

    ```py
    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] 
    ```

    在早期版本中,这两个结构之间存在差异:

    +   `df.loc[[3]]`将返回一个由 3 重新索引的框架(所有值为`np.nan`)

    +   `df.loc[[3],:]`会引发`KeyError`。

    现在两者都会引发`KeyError`。规则是使用类似列表和`.loc`时必须找到*至少 1*个索引器([GH 7999](https://github.com/pandas-dev/pandas/issues/7999))

    此外,在早期版本中,这两者也是不同的:

    +   `df.loc[[1,3]]`将返回一个由[1,3]重新索引的框架

    +   `df.loc[[1,3],:]`会引发`KeyError`。

    现在两者都将返回由[1,3]重新索引的框架。例如

    ```py
    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`进行多轴索引时看到。

    ```py
    >>> 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`:

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

    此外,如果在具有类似列表索引器的 MultiIndex 中找不到任何值,`.loc`将引发错误:

    ```py
    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](https://github.com/pandas-dev/pandas/issues/7941))。

    以前,在数值容器中将`None`赋值会将 dtype 更改为 object(或者根据调用而出错)。现在使用`NaN`:

    ```py
    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`值)。

    ```py
    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](https://github.com/pandas-dev/pandas/issues/8511), [GH 5104](https://github.com/pandas-dev/pandas/issues/5104))

    ```py
    In [72]: s = pd.Series([1, 2, 3])

    In [73]: s2 = s

    In [74]: s += 1.5 
    ```

    v0.15.0 之前的行为

    ```py
    # 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 
    ```

    现在这是正确的行为

    ```py
    # 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](https://github.com/pandas-dev/pandas/issues/4466))

+   将插入到 Series/DataFrame 中的 UTC 本地化的时间序列/索引将保留 UTC 时区,并插入为`object` dtype,而不是转换为一个 naive 的`datetime64[ns]`([GH 8411](https://github.com/pandas-dev/pandas/issues/8411))。

+   在从字典构建 DataFrame 时,传递具有时区的`DatetimeIndex`的错误未被保留([GH 7822](https://github.com/pandas-dev/pandas/issues/7822))

    在早期版本中,这将删除时区,现在保留时区,但会给出一个`object` dtype 的列:

    ```py
    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](https://github.com/pandas-dev/pandas/issues/7660)). 参见 通过堆叠和展开进行重塑.

+   在使用 ‘fixed’ 格式时,如果 `df` 有非唯一列,则 `df.to_hdf` 将引发 `ValueError`,因为生成的文件将会损坏 ([GH 7761](https://github.com/pandas-dev/pandas/issues/7761))

+   使用链式赋值在切片的混合 dtype 数据框上设置值时,根据选项 `mode.chained_assignment`,会发出 `SettingWithCopy` 的警告或者错误提示。([GH 7845](https://github.com/pandas-dev/pandas/issues/7845), [GH 7950](https://github.com/pandas-dev/pandas/issues/7950))

    ```py
    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](https://github.com/pandas-dev/pandas/issues/7737)).

+   以前,对混合 dtype 数据框进行扩展会与 `.append` 的行为不同,后者会保留 dtype(相关 [GH 2578](https://github.com/pandas-dev/pandas/issues/2578), [GH 8176](https://github.com/pandas-dev/pandas/issues/8176)):

    ```py
    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 
    ```

+   当 `path=None` 时,`Series.to_csv()` 现在返回一个字符串,与 `DataFrame.to_csv()` 的行为匹配 ([GH 8215](https://github.com/pandas-dev/pandas/issues/8215)).

+   当传递不存在的文件时,`read_hdf` 现在会引发 `IOError`。以前,会创建一个新的空文件,并引发 `KeyError` ([GH 7715](https://github.com/pandas-dev/pandas/issues/7715)).

+   `DataFrame.info()` 现在在输出末尾加入了一个换行符 ([GH 8114](https://github.com/pandas-dev/pandas/issues/8114))

+   现在连接不同对象将引发 `ValueError` 而不是原始的 `Exception`。

+   合并错误现在将是 `ValueError` 的子类,而不是原始的 `Exception` ([GH 8501](https://github.com/pandas-dev/pandas/issues/8501))

+   `DataFrame.plot` 和 `Series.plot` 关键字现在具有一致的顺序 ([GH 8037](https://github.com/pandas-dev/pandas/issues/8037))  ### 内部重构

在 0.15.0 中,`Index` 在内部已经被重新设计,不再是 `ndarray` 的子类,而是子类 `PandasObject`,类似于 pandas 其他对象。这个改变使得新建索引类型的子类和创建变得非常容易。这应该是一个透明的变化,只有非常有限的 API 影响 ([GH 5080](https://github.com/pandas-dev/pandas/issues/5080), [GH 7439](https://github.com/pandas-dev/pandas/issues/7439), [GH 7796](https://github.com/pandas-dev/pandas/issues/7796), [GH 8024](https://github.com/pandas-dev/pandas/issues/8024), [GH 8367](https://github.com/pandas-dev/pandas/issues/8367), [GH 7997](https://github.com/pandas-dev/pandas/issues/7997), [GH 8522](https://github.com/pandas-dev/pandas/issues/8522)):

+   您可能需要使用 `pd.read_pickle` 而不是 `pickle.load` 来解除 pandas 版本 < 0.15.0 的 pickle。请参阅 pickle 文档

+   当使用 `PeriodIndex` 绘图时,matplotlib 的内部轴现在将是 `Period` 的数组,而不是 `PeriodIndex`(这类似于现在 `DatetimeIndex` 传递的 `datetimes` 数组)

+   多重索引现在会像其他 pandas 对象一样提升到关于真值测试的类似程度,请参阅此处([GH 7897](https://github.com/pandas-dev/pandas/issues/7897))。

+   当直接使用 matplotlib 的 `plot` 函数绘制 DatetimeIndex 时,轴标签将不再以日期格式显示,而是以整数格式显示(`datetime64` 的内部表示)。 **更新** 这在 0.15.1 版中已修复,请参阅此处。  ### 弃用

+   `Categorical` 的 `labels` 和 `levels` 属性已弃用,并重命名为 `codes` 和 `categories`。

+   `pd.DataFrame.to_dict` 的 `outtype` 参数已被弃用,改用 `orient`。([GH 7840](https://github.com/pandas-dev/pandas/issues/7840))

+   `convert_dummies` 方法已被弃用,改用 `get_dummies`([GH 8140](https://github.com/pandas-dev/pandas/issues/8140))

+   在 `tz_localize` 中的 `infer_dst` 参数将被弃用,改用 `ambiguous` 来提供更灵活的处理夏令时转换的方法。将 `infer_dst=True` 替换为 `ambiguous='infer'` 可获得相同的行为([GH 7943](https://github.com/pandas-dev/pandas/issues/7943))。有关更多详细信息,请参阅文档。

+   顶级 `pd.value_range` 已被弃用,可以被 `.describe()` 替换([GH 8481](https://github.com/pandas-dev/pandas/issues/8481))

+   `Index` 集合操作 `+` 和 `-` 已被弃用,以提供这些操作用于某些索引类型的数值类型操作。`+` 可以被 `.union()` 或 `|` 替换,`-` 可以被 `.difference()` 替换。此外,方法名 `Index.diff()` 已被弃用,可以被 `Index.difference()` 替换([GH 8226](https://github.com/pandas-dev/pandas/issues/8226))

    ```py
    # +
    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'])) 
    ```

    ```py
    # -
    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](https://github.com/pandas-dev/pandas/issues/7762)、[GH 7032](https://github.com/pandas-dev/pandas/issues/7032))。### 删除之前版本的弃用/更改

+   删除 `DataFrame.delevel` 方法,改用 `DataFrame.reset_index`  ## 增强功能

改进了导入/导出 Stata 文件的功能:

+   在 `to_stata` 中添加了对 bool、uint8、uint16 和 uint32 数据类型的支持([GH 7097](https://github.com/pandas-dev/pandas/issues/7097)、[GH 7365](https://github.com/pandas-dev/pandas/issues/7365))

+   导入 Stata 文件时添加了转换选项([GH 8527](https://github.com/pandas-dev/pandas/issues/8527))

+   `DataFrame.to_stata` 和 `StataWriter` 检查字符串长度,以确保与 dta 文件中施加的限制的兼容性,其中固定宽度字符串必须包含 244 个或更少字符。尝试写入超过 244 个字符的字符串的 Stata dta 文件将引发 `ValueError`。 ([GH 7858](https://github.com/pandas-dev/pandas/issues/7858))。

+   `read_stata` 和 `StataReader` 可以通过将参数 `convert_missing` 设置为 `True` 将丢失的数据信息导入到 `DataFrame` 中。当使用此选项时,丢失的值将作为 `StataMissingValue` 对象返回,包含缺失值的列将具有 `object` 数据类型。 ([GH 8045](https://github.com/pandas-dev/pandas/issues/8045))。

绘图函数的增强:

+   在 `DataFrame.plot` 中添加了 `layout` 关键字。你可以传递一个元组 `(rows, columns)`,其中一个可以是 `-1` 以自动推断 ([GH 6667](https://github.com/pandas-dev/pandas/issues/6667), [GH 8071](https://github.com/pandas-dev/pandas/issues/8071))。

+   允许将多个轴传递给 `DataFrame.plot`、`hist` 和 `boxplot` ([GH 5353](https://github.com/pandas-dev/pandas/issues/5353), [GH 6970](https://github.com/pandas-dev/pandas/issues/6970), [GH 7069](https://github.com/pandas-dev/pandas/issues/7069))。

+   为 `DataFrame.plot` 添加了对 `c`、`colormap` 和 `colorbar` 参数的支持,其中 `kind='scatter'` ([GH 7780](https://github.com/pandas-dev/pandas/issues/7780))。

+   使用 `kind='hist'` 的 `DataFrame.plot` 中的直方图 ([GH 7809](https://github.com/pandas-dev/pandas/issues/7809)),请参阅文档。

+   使用 `kind='box'` 的 `DataFrame.plot` 中的箱线图 ([GH 7998](https://github.com/pandas-dev/pandas/issues/7998)),请参阅文档。

其他:

+   `read_csv` 现在有一个关键字参数 `float_precision`,用于指定 C 引擎在解析过程中应使用的浮点转换器,请参阅此处 ([GH 8002](https://github.com/pandas-dev/pandas/issues/8002), [GH 8044](https://github.com/pandas-dev/pandas/issues/8044))。

+   向 `Series` 对象添加了 `searchsorted` 方法 ([GH 7447](https://github.com/pandas-dev/pandas/issues/7447))。

+   对混合类型数据框的 `describe()` 更加灵活。现在可以通过 `include`/`exclude` 参数进行基于类型的列过滤。请参阅文档 ([GH 8164](https://github.com/pandas-dev/pandas/issues/8164))。

    ```py
    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’ 可以请求所有列。

    ```py
    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_dict` 的 `orient` 参数中添加了 `split` 作为选项。 ([GH 7840](https://github.com/pandas-dev/pandas/issues/7840))。

+   `get_dummies` 方法现在可以用于 DataFrame。默认情况下,只有分类列被编码为 0 和 1,而其他列保持不变。

    ```py
    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] 
    ```

+   `PeriodIndex` 支持 `resolution`,与 `DatetimeIndex` 相同([GH 7708](https://github.com/pandas-dev/pandas/issues/7708))

+   `pandas.tseries.holiday` 添加了对其他节日和观察节日方式的支持([GH 7070](https://github.com/pandas-dev/pandas/issues/7070))

+   `pandas.tseries.holiday.Holiday` 现在支持 Python3 中的偏移量列表([GH 7070](https://github.com/pandas-dev/pandas/issues/7070))

+   `pandas.tseries.holiday.Holiday` 现在支持一个 `days_of_week` 参数([GH 7070](https://github.com/pandas-dev/pandas/issues/7070))

+   `GroupBy.nth()` 现在支持选择多个第 n 个值([GH 7910](https://github.com/pandas-dev/pandas/issues/7910))

    ```py
    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` 和 `PeriodIndex` 支持与 `timedelta` 类似的加法/减法([GH 7966](https://github.com/pandas-dev/pandas/issues/7966))

    如果 `Period` 频率是 `D`、`H`、`T`、`S`、`L`、`U`、`N`,且结果可以具有相同的频率,则可以添加 `Timedelta`-like。否则,只能添加相同的 `offsets`。

    ```py
    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]') 
    ```

+   添加了与 `openpyxl` 版本 >= 2.0 的实验性兼容性。`DataFrame.to_excel` 方法的 `engine` 关键字现在识别 `openpyxl1` 和 `openpyxl2`,分别显式要求 openpyxl v1 和 v2,如果请求的版本不可用则失败。`openpyxl` 引擎现在是一个元引擎,自动使用已安装的 openpyxl 版本([GH 7177](https://github.com/pandas-dev/pandas/issues/7177))

+   `DataFrame.fillna` 现在可以接受一个 `DataFrame` 作为填充值([GH 8377](https://github.com/pandas-dev/pandas/issues/8377))

+   当传递多个级别编号时,`stack()` 现在会起作用。请参阅 Reshaping by stacking and unstacking。([GH 7660](https://github.com/pandas-dev/pandas/issues/7660))

+   `set_names()`、`set_labels()` 和 `set_levels()` 方法现在都接受一个可选的 `level` 关键字参数,用于修改 MultiIndex 的特定级别。另外,当操作 `Index` 或 `MultiIndex` 的特定级别时,`set_names()` 现在接受一个标量字符串值([GH 7792](https://github.com/pandas-dev/pandas/issues/7792))

    ```py
    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](https://github.com/pandas-dev/pandas/issues/7892), [GH 7890](https://github.com/pandas-dev/pandas/issues/7890))

    ```py
    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) 
    ```

+   `Index` 现在支持 `duplicated` 和 `drop_duplicates`。([GH 4060](https://github.com/pandas-dev/pandas/issues/4060))

    ```py
    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.concat` 添加了 `copy=True` 参数,以启用完整块的传递([GH 8252](https://github.com/pandas-dev/pandas/issues/8252))

+   为 numpy 1.8+数据类型(`bool_`、`int_`、`float_`、`string_`)添加了转换为 R dataframe 的支持([GH 8400](https://github.com/pandas-dev/pandas/issues/8400))  ## 性能

+   改进了`DatetimeIndex.__iter__`的性能,以实现更快的迭代([GH 7683](https://github.com/pandas-dev/pandas/issues/7683))

+   `Period`创建(和`PeriodIndex` setitem)的性能改进([GH 5155](https://github.com/pandas-dev/pandas/issues/5155))

+   Series.transform 的性能改进,获得了显著的性能提升(修订版)([GH 6496](https://github.com/pandas-dev/pandas/issues/6496))

+   在读取大文件时改进了`StataReader`的性能([GH 8040](https://github.com/pandas-dev/pandas/issues/8040), [GH 8073](https://github.com/pandas-dev/pandas/issues/8073))

+   在写入大文件时改进了`StataWriter`的性能([GH 8079](https://github.com/pandas-dev/pandas/issues/8079))

+   在多键`groupby`中的性能和内存使用方面进行了改进([GH 8128](https://github.com/pandas-dev/pandas/issues/8128))

+   在 groupby `.agg`和`.apply`中的性能改进,未将内置的 max/min 映射到 numpy/cythonized 版本的错误([GH 7722](https://github.com/pandas-dev/pandas/issues/7722))

+   写入 sql(`to_sql`)的性能提高了 50%([GH 8208](https://github.com/pandas-dev/pandas/issues/8208))。

+   对大量 ngroups 的 groupby 性能进行基准测试([GH 6787](https://github.com/pandas-dev/pandas/issues/6787))

+   在`CustomBusinessDay`、`CustomBusinessMonth`中的性能改进([GH 8236](https://github.com/pandas-dev/pandas/issues/8236))

+   对包含日期时间的多级索引的`MultiIndex.values`的性能改进([GH 8543](https://github.com/pandas-dev/pandas/issues/8543))  ## 修复错误

+   在使用边距和字典 aggfunc 时,pivot_table 中的错误([GH 8349](https://github.com/pandas-dev/pandas/issues/8349))

+   在`read_csv`中,`squeeze=True`会返回一个视图的错误([GH 8217](https://github.com/pandas-dev/pandas/issues/8217))

+   在某些情况下检查`read_sql`中表名的错误([GH 7826](https://github.com/pandas-dev/pandas/issues/7826))。

+   在指定频率时,`DataFrame.groupby`中`Grouper`不识别级别的错误([GH 7885](https://github.com/pandas-dev/pandas/issues/7885))

+   在将 DataFrame 保存到 SQL 表时,多索引 dtype 混淆的错误([GH 8021](https://github.com/pandas-dev/pandas/issues/8021))

+   在具有浮点数和整数操作数 dtype 的`Series` 0-division 中的错误([GH 7785](https://github.com/pandas-dev/pandas/issues/7785))

+   在`Series.astype("unicode")`中,未正确调用值的`unicode`的错误([GH 7758](https://github.com/pandas-dev/pandas/issues/7758))

+   在混合了`datetime64[ns]`和`timedelta64[ns]` dtype 的情况下,`DataFrame.as_matrix()`中的错误([GH 7778](https://github.com/pandas-dev/pandas/issues/7778))

+   在选择`DatetimeIndex`时`HDFStore.select_column()`不会保留 UTC 时区信息([GH 7777](https://github.com/pandas-dev/pandas/issues/7777))

+   在指定`format='%Y%m%d'`和`coerce=True`时`to_datetime`中的错误,先前返回对象数组(而不是具有`NaT`的强制时间序列)([GH 7930](https://github.com/pandas-dev/pandas/issues/7930))

+   在`DatetimeIndex`和`PeriodIndex`的原地加法和减法导致与正常结果不同的错误([GH 6527](https://github.com/pandas-dev/pandas/issues/6527))

+   在添加和减去`PeriodIndex`与`PeriodIndex`时引发`TypeError`的错误([GH 7741](https://github.com/pandas-dev/pandas/issues/7741))

+   在`combine_first`中使用`PeriodIndex`数据引发`TypeError`的错误([GH 3367](https://github.com/pandas-dev/pandas/issues/3367))

+   在缺少索引器的`MultiIndex`切片中的错误([GH 7866](https://github.com/pandas-dev/pandas/issues/7866))

+   在各种边缘情况下切片`MultiIndex`中的错误([GH 8132](https://github.com/pandas-dev/pandas/issues/8132))

+   在具有非标量类型对象的`MultiIndex`索引中的回归错误([GH 7914](https://github.com/pandas-dev/pandas/issues/7914))

+   在`Timestamp`与`int64`类型的比较中的错误��[GH 8058](https://github.com/pandas-dev/pandas/issues/8058))

+   在`pickles`中包含`DateOffset`可能在内部引用`normalize`属性时引发`AttributeError`的错误([GH 7748](https://github.com/pandas-dev/pandas/issues/7748))

+   在使用`major_xs`和传递`copy=False`时`Panel`中的错误(由于缺少`warnings`而导致弃用警告失败)([GH 8152](https://github.com/pandas-dev/pandas/issues/8152))

+   反序列化`pickle`中的错误,对于先前版本为 0.14.1 的容器存在重复项时会失败,试图避免匹配块和管理器项时的歧义,当只有一个块时就没有歧义([GH 7794](https://github.com/pandas-dev/pandas/issues/7794))

+   将`PeriodIndex`放入`Series`中会转换为`int64`类型,而不是`Periods`的`object`的错误([GH 7932](https://github.com/pandas-dev/pandas/issues/7932))

+   在传递`where`时`HDFStore`迭代中的错误([GH 8014](https://github.com/pandas-dev/pandas/issues/8014))

+   在使用传递的非排序键进行转换时`DataFrameGroupby.transform`中的错误([GH 8046](https://github.com/pandas-dev/pandas/issues/8046),[GH 8430](https://github.com/pandas-dev/pandas/issues/8430))

+   在重复时间序列线和区域图中可能导致`ValueError`或不正确类型的错误([GH 7733](https://github.com/pandas-dev/pandas/issues/7733))

+   在具有`datetime.date`输入的`MultiIndex`推断中的错误([GH 7888](https://github.com/pandas-dev/pandas/issues/7888))

+   在`get`中,`IndexError`不会导致返回默认值的错误([GH 7725](https://github.com/pandas-dev/pandas/issues/7725))

+   在`offsets.apply`、`rollforward`和`rollback`中可能重置纳秒的错误([GH 7697](https://github.com/pandas-dev/pandas/issues/7697))

+   `offsets.apply`、`rollforward` 和 `rollback` 中的 Bug,如果 `Timestamp` 具有 `dateutil` 时区信息,则可能会引发 `AttributeError` ([GH 7697](https://github.com/pandas-dev/pandas/issues/7697))

+   使用 `Float64Index` 对 MultiIndex 帧进行排序时出现 Bug ([GH 8017](https://github.com/pandas-dev/pandas/issues/8017))

+   不一致的面板设置项中存在 Bug,对齐右侧边的 `DataFrame` 时 ([GH 7763](https://github.com/pandas-dev/pandas/issues/7763))

+   `is_superperiod` 和 `is_subperiod` 中存在 Bug,不能处理高于 `S` 的更高频率 ([GH 7760](https://github.com/pandas-dev/pandas/issues/7760), [GH 7772](https://github.com/pandas-dev/pandas/issues/7772), [GH 7803](https://github.com/pandas-dev/pandas/issues/7803))

+   在 32 位平台上,`Series.shift` 中存在 Bug ([GH 8129](https://github.com/pandas-dev/pandas/issues/8129))

+   `PeriodIndex.unique` 中存在 Bug,返回 int64 `np.ndarray` ([GH 7540](https://github.com/pandas-dev/pandas/issues/7540))

+   `groupby.apply` 中的 Bug,函数中存在不影响的突变时可能会引发 `AttributeError` ([GH 8467](https://github.com/pandas-dev/pandas/issues/8467))

+   `DataFrame.reset_index` 中的 Bug,当 `MultiIndex` 包含 `PeriodIndex` 或 `DatetimeIndex` 时,引发 `ValueError` ([GH 7746](https://github.com/pandas-dev/pandas/issues/7746), [GH 7793](https://github.com/pandas-dev/pandas/issues/7793))

+   `DataFrame.plot` 中存在 Bug,当 `subplots=True` 时,可能会绘制不必要的次要 xticks 和 yticks ([GH 7801](https://github.com/pandas-dev/pandas/issues/7801))

+   `StataReader` 中的 Bug,由于 Stata 文档和实现之间的差异,117 个文件中的变量标签没有被读取 ([GH 7816](https://github.com/pandas-dev/pandas/issues/7816))

+   `StataReader` 中的 Bug,字符串总是被转换为 244 个字符的固定宽度,而不考虑底层字符串大小 ([GH 7858](https://github.com/pandas-dev/pandas/issues/7858))

+   `DataFrame.plot` 和 `Series.plot` 中的 Bug 可能会忽略 `rot` 和 `fontsize` 关键字 ([GH 7844](https://github.com/pandas-dev/pandas/issues/7844))

+   `DatetimeIndex.value_counts` 中存在 Bug,不保留时区信息 ([GH 7735](https://github.com/pandas-dev/pandas/issues/7735))

+   `PeriodIndex.value_counts` 中的 Bug 导致 `Int64Index` 的结果 ([GH 7735](https://github.com/pandas-dev/pandas/issues/7735))

+   `DataFrame.join` 中存在 Bug,在索引上进行左连接时存在多个匹配项 ([GH 5391](https://github.com/pandas-dev/pandas/issues/5391))

+   `GroupBy.transform()` 中的 Bug,使用不保留索引的转换的 int 分组会被错误地截断 ([GH 7972](https://github.com/pandas-dev/pandas/issues/7972))

+   `groupby` 中的 Bug,没有名称属性的可调用对象会选择错误的路径,并生成一个 `DataFrame` 而不是一个 `Series` ([GH 7929](https://github.com/pandas-dev/pandas/issues/7929))

+   当 DataFrame 分组列重复时,`groupby` 中存在 Bug,错误消息 ([GH 7511](https://github.com/pandas-dev/pandas/issues/7511))

+   在 `read_html` 中存在的问题,`infer_types` 参数错误地强制转换了日期类似对象([GH 7762](https://github.com/pandas-dev/pandas/issues/7762), [GH 7032](https://github.com/pandas-dev/pandas/issues/7032))。

+   在具有索引的 `Series.str.cat` 中存在的问题,被过滤为不包含第一个项([GH 7857](https://github.com/pandas-dev/pandas/issues/7857))。

+   `Timestamp` 中无法从字符串中解析 `nanosecond`([GH 7878](https://github.com/pandas-dev/pandas/issues/7878))。

+   带有字符串偏移和 `tz` 的 `Timestamp` 结果不正确([GH 7833](https://github.com/pandas-dev/pandas/issues/7833))。

+   在 `tslib.tz_convert` 和 `tslib.tz_convert_single` 中存在的问题可能会返回不同的结果([GH 7798](https://github.com/pandas-dev/pandas/issues/7798))。

+   在具有时区的非重叠时间戳的 `DatetimeIndex.intersection` 中存在的问题会引发 `IndexError`([GH 7880](https://github.com/pandas-dev/pandas/issues/7880))。

+   在 TimeOps 和非唯一索引对齐中存在的问题([GH 8363](https://github.com/pandas-dev/pandas/issues/8363))。

+   在 `GroupBy.filter()` 中存在的问题,快速路径与慢速路径使过滤器返回一个看似有效但实际上无效的非标量值([GH 7870](https://github.com/pandas-dev/pandas/issues/7870))。

+   当时区是从输入日期中推断出的但在跨越夏令时边界时返回错误时间时,在 `date_range()`/`DatetimeIndex()` 中存在的问题([GH 7835](https://github.com/pandas-dev/pandas/issues/7835), [GH 7901](https://github.com/pandas-dev/pandas/issues/7901))。

+   在 `to_excel()` 中存在的问题,负无穷被附加了负号,而正无穷则不存在([GH 7949](https://github.com/pandas-dev/pandas/issues/7949))。

+   在 `stacked=True` 时,区域图绘制的图例具有不正确的 `alpha`([GH 8027](https://github.com/pandas-dev/pandas/issues/8027))。

+   使用 `np.timedelta64` 进行 `Period` 和 `PeriodIndex` 的加法/减法会导致内部表示不正确([GH 7740](https://github.com/pandas-dev/pandas/issues/7740))。

+   在没有偏移或观察时的 `Holiday` 中存在的问题([GH 7987](https://github.com/pandas-dev/pandas/issues/7987))。

+   当列或索引是 `MultiIndex` 时,`DataFrame.to_latex` 格式化存在问题([GH 7982](https://github.com/pandas-dev/pandas/issues/7982))。

+   在夏令时周围的 `DateOffset` 中存在的问题会产生意外结果([GH 5175](https://github.com/pandas-dev/pandas/issues/5175))。

+   在 `DataFrame.shift` 中存在的问题,空列会在 numpy 1.7 上引发 `ZeroDivisionError`([GH 8019](https://github.com/pandas-dev/pandas/issues/8019))。

+   安装中存在的问题,`html_encoding/*.html` 未被安装,因此一些测试未能正确运行([GH 7927](https://github.com/pandas-dev/pandas/issues/7927))。

+   在 `read_html` 中存在的问题,`bytes` 对象未在 `_read` 中进行测试([GH 7927](https://github.com/pandas-dev/pandas/issues/7927))。

+   当一个列级别是日期样式时,`DataFrame.stack()` 存在的问题([GH 8039](https://github.com/pandas-dev/pandas/issues/8039))。

+   与 `DataFrame` 广播 numpy 标量的 Bug([GH 8116](https://github.com/pandas-dev/pandas/issues/8116))。

+   在没有名称的 `index` 和 `columns` 上执行的 `pivot_table` 引发 `KeyError`([GH 8103](https://github.com/pandas-dev/pandas/issues/8103))。

+   当颜色由 `c` 关键字指定时,`DataFrame.plot(kind='scatter')` 中的 Bug 会以不同颜色绘制点和误差条([GH 8081](https://github.com/pandas-dev/pandas/issues/8081))。

+   `Float64Index` 中的 Bug,`iat` 和 `at` 未进行测试且失败([GH 8092](https://github.com/pandas-dev/pandas/issues/8092))。

+   在 `DataFrame.boxplot()` 中,当生成多个轴时未正确设置 y 轴限制的 Bug([GH 7528](https://github.com/pandas-dev/pandas/issues/7528), [GH 5517](https://github.com/pandas-dev/pandas/issues/5517))。

+   在 `read_csv` 中,行注释在给定自定义行终止符或 `delim_whitespace=True` 时未正确处理([GH 8122](https://github.com/pandas-dev/pandas/issues/8122))。

+   `read_html` 中的 Bug,空表导致 `StopIteration`([GH 7575](https://github.com/pandas-dev/pandas/issues/7575))。

+   在设置相同 dtype 块中的列时进行转换时的 Bug([GH 7704](https://github.com/pandas-dev/pandas/issues/7704))。

+   在 `GroupBy` 中访问组时的 Bug,当原始分组器是元组时([GH 8121](https://github.com/pandas-dev/pandas/issues/8121))。

+   在 `.at` 中,将整数索引器应用于非整数索引并进行回退的 Bug([GH 7814](https://github.com/pandas-dev/pandas/issues/7814))。

+   kde 绘图和 NaN 的 Bug([GH 8182](https://github.com/pandas-dev/pandas/issues/8182))。

+   在 `GroupBy.count` 中,float32 数据类型的 Bug,nan 值未排除([GH 8169](https://github.com/pandas-dev/pandas/issues/8169))。

+   堆叠条形图和 NaN 的 Bug([GH 8175](https://github.com/pandas-dev/pandas/issues/8175))。

+   与非均匀可整除偏移(例如 '7s')的重新采样中的 Bug([GH 8371](https://github.com/pandas-dev/pandas/issues/8371))。

+   插值方法中的 Bug 在使用 `limit` 关键字时,当不需要插值数值时出现问题([GH 7173](https://github.com/pandas-dev/pandas/issues/7173))。

+   在 `DataFrame.to_string()` 中忽略了 `header=False` 时 `col_space` 的 Bug([GH 8230](https://github.com/pandas-dev/pandas/issues/8230))。

+   `DatetimeIndex.asof` 中的 Bug 不正确地匹配部分字符串并返回错误的日期([GH 8245](https://github.com/pandas-dev/pandas/issues/8245))。

+   在修改全局 matplotlib rcParams 的绘图方法中的 Bug([GH 8242](https://github.com/pandas-dev/pandas/issues/8242))。

+   `DataFrame.__setitem__` 中的 Bug,当将数据框列设置为稀疏数组时引发错误([GH 8131](https://github.com/pandas-dev/pandas/issues/8131))。

+   当整列为空时,`Dataframe.boxplot()` 失败的 Bug([GH 8181](https://github.com/pandas-dev/pandas/issues/8181))。

+   在 `radviz` 可视化中出现的变量混乱 Bug([GH 8199](https://github.com/pandas-dev/pandas/issues/8199))。

+   在使用带有`limit`关键字的插值方法时出现插值不需要的值时的 Bug([GH 7173](https://github.com/pandas-dev/pandas/issues/7173))。

+   在`DataFrame.to_string()`中的 Bug,当`header=False`时忽略了`col_space`([GH 8230](https://github.com/pandas-dev/pandas/issues/8230))。

+   在`to_clipboard`中的 Bug,会剪切长列数据([GH 8305](https://github.com/pandas-dev/pandas/issues/8305))

+   在`DataFrame`终端显示中的 Bug:将 max_column/max_rows 设置为零不会触发自动调整 dfs 以适应终端宽度/高度([GH 7180](https://github.com/pandas-dev/pandas/issues/7180))。

+   在 OLS 中出现的 Bug,当运行带有“cluster”和“nw_lags”参数时无法正确工作,但也不会抛出错误([GH 5884](https://github.com/pandas-dev/pandas/issues/5884))。

+   在`DataFrame.dropna`中出现的 Bug,将子集参数中不存在的列解释为“最后一列”([GH 8303](https://github.com/pandas-dev/pandas/issues/8303))。

+   在非单调非唯一索引上的`Index.intersection`中的 Bug([GH 8362](https://github.com/pandas-dev/pandas/issues/8362))。

+   在掩码系列赋值中出现的 Bug,类型不匹配会破坏对齐性([GH 8387](https://github.com/pandas-dev/pandas/issues/8387))。

+   在`NDFrame.equals`中的 Bug,dtype=object 时会产生假阴性结果([GH 8437](https://github.com/pandas-dev/pandas/issues/8437))。

+   在索引器赋值时出现的 Bug,当类型不一致时会破坏对齐性([GH 8258](https://github.com/pandas-dev/pandas/issues/8258))。

+   在`NDFrame.loc`索引中的 Bug,当行/列名称在目标是列表/ndarray 时丢失时([GH 6552](https://github.com/pandas-dev/pandas/issues/6552))。

+   在`NDFrame.loc`索引中的回归,当行/列转换为 Float64Index,如果目标是空列表/ndarray,则会出现错误([GH 7774](https://github.com/pandas-dev/pandas/issues/7774))。

+   在`Series`中的 Bug,允许通过 `DataFrame` 索引它会产生意外结果。不再允许此类索引([GH 8444](https://github.com/pandas-dev/pandas/issues/8444))。

+   在具有 MultiIndex 列的`DataFrame`的项目赋值中的 Bug,右侧列不对齐([GH 7655](https://github.com/pandas-dev/pandas/issues/7655))。

+   抑制 NumPy 生成的 FutureWarning,当比较包含 NaN 的对象数组时,用于相等性判断([GH 7065](https://github.com/pandas-dev/pandas/issues/7065))。

+   在`DataFrame.eval()`中出现的 Bug,`not`运算符(`~`)的 dtype 没有正确地被推断为`bool`。## 贡献者

总共有 80 人为这个版本贡献了补丁。名字后面带有“+”符号的人第一次为此版本贡献了补丁。

+   Aaron Schumacher +

+   Adam Greenhall

+   Andy Hayden

+   Anthony O’Brien +

+   Artemy Kolchinsky +

+   Ben Schiller +

+   Benedikt Sauer

+   Benjamin Thyreau +

+   BorisVerk +

+   Chris Reynolds +

+   Chris Stoafer +

+   DSM

+   Dav Clark +

+   FragLegs +

+   German Gomez-Herrero +

+   Hsiaoming Yang +

+   Huan Li +

+   Hyungtae Kim +

+   Isaac Slavitt +

+   Jacob Schaer

+   Jacob Wasserman +

+   Jan Schulz

+   Jeff Reback

+   Jeff Tratner

+   Jesse Farnham +

+   Joe Bradish +

+   Joerg Rittinger +

+   John W. O’Brien

+   Joris Van den Bossche

+   Kevin Sheppard

+   Kyle Meyer

+   Max Chang +

+   Michael Mueller

+   Michael W Schatzow +

+   Mike Kelly

+   Mortada Mehyar

+   Nathan Sanders +

+   Nathan Typanski +

+   Paul Masurel +

+   Phillip Cloud

+   Pietro Battiston

+   RenzoBertocchi +

+   Ross Petchler +

+   Shahul Hameed +

+   Shashank Agarwal +

+   Stephan Hoyer

+   Tom Augspurger

+   TomAugspurger

+   Tony Lorenzo +

+   Wes Turner

+   Wilfred Hughes +

+   Yevgeniy Grechka +

+   Yoshiki Vázquez Baeza +

+   behzad nouri +

+   benjamin

+   bjonen +

+   dlovell +

+   dsm054

+   hunterowens +

+   immerrr

+   ischwabacher

+   jmorris0x0 +

+   jnmclarty +

+   jreback

+   klonuo +

+   lexual

+   mcjcode +

+   mtrbean +

+   onesandzeroes

+   rockg

+   seth-p

+   sinhrks

+   someben +

+   stahlous +

+   stas-sl +

+   thatneat +

+   tom-alcorn +

+   unknown

+   unutbu

+   zachcp +

## 新特性

### `Series/DataFrame` 中的分类变量

`Categorical`现在可以包含在`Series`和`DataFrames`中,并且获得了新的操纵方法。感谢 Jan Schulz 为此 API/实现做出的贡献。([GH 3943](https://github.com/pandas-dev/pandas/issues/3943), [GH 5313](https://github.com/pandas-dev/pandas/issues/5313), [GH 5314](https://github.com/pandas-dev/pandas/issues/5314), [GH 7444](https://github.com/pandas-dev/pandas/issues/7444), [GH 7839](https://github.com/pandas-dev/pandas/issues/7839), [GH 7848](https://github.com/pandas-dev/pandas/issues/7848), [GH 7864](https://github.com/pandas-dev/pandas/issues/7864), [GH 7914](https://github.com/pandas-dev/pandas/issues/7914), [GH 7768](https://github.com/pandas-dev/pandas/issues/7768), [GH 8006](https://github.com/pandas-dev/pandas/issues/8006), [GH 3678](https://github.com/pandas-dev/pandas/issues/3678), [GH 8075](https://github.com/pandas-dev/pandas/issues/8075), [GH 8076](https://github.com/pandas-dev/pandas/issues/8076), [GH 8143](https://github.com/pandas-dev/pandas/issues/8143), [GH 8453](https://github.com/pandas-dev/pandas/issues/8453), [GH 8518](https://github.com/pandas-dev/pandas/issues/8518))。

完整文档请参阅分类介绍和 API 文档。

```py
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_aggpandas.core.factor_agg已被移除。作为替代,请构建一个 DataFrame 并使用df.groupby(<group>).agg(<func>)

  • Categorical构造函数提供“codes/labels 和 levels”参数不再支持。现在将构造函数提供两个参数解释为“values 和 levels(现在称为‘categories’)”。请修改您的代码以使用from_codes()构造函数。

  • Categorical.labels属性已重命名为Categorical.codes,且为只读属性。如果您想操纵 codes,请使用 Categoricals 上的 API 方法之一。

  • Categorical.levels 属性更名为 Categorical.categories。### TimedeltaIndex/scalar

我们引入了一个新的标量类型 Timedelta,它是 datetime.timedelta 的子类,并且行为类似,但允许与 np.timedelta64 类型以及大量自定义表示、解析和属性兼容。这种类型与 Timestamp 处理 datetimes 的方式非常相似。它是类型的一个美观的 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 返回 小时分钟 之间组合的总秒数。相反,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 版本更新内容

警告

在 0.15.0 之前,对于类似列表/系列的输入,pd.to_timedelta 会返回一个 Series,对于标量输入则会返回一个 np.timedelta64。现在,对于类似列表的输入,它将返回一个 TimedeltaIndex,对于系列输入,它将返回一个 Series,对于标量输入,它将返回一个 Timedelta

pd.to_timedelta 的参数现在是 (arg,unit='ns',box=True,coerce=False),之前是 (arg,box=True,unit='ns'),因为这样更合乎逻辑。

构造一个标量

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')] 
  • 对系列进行迭代,例如 list(Series(...))timedelta64[ns],在 v0.15.0 之前,每个元素都会返回 np.timedelta64。现在这些将被包装在 Timedelta 中。### 内存使用量

实现了查找 DataFrame 内存使用量的方法。更多信息请参见 FAQ。(GH 6852).

新的显示选项 display.memory_usage(参见 选项和设置)设置了 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), datetime64ns, float64(1), int64(1), object(1), timedelta64ns
memory usage: 288.2+ KB 

此外 memory_usage() 是一个可用于 dataframe 对象的方法,它返回每列的内存使用情况。

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 访问器

`Series` 增加了一个访问器,用于简洁地返回 Series 的 *values* 的日期时间属性,如果它是日期时间/周期类型的 Series。 ([GH 7207](https://github.com/pandas-dev/pandas/issues/7207)) 这将返回一个 Series,索引与现有的 Series 相同。参见 文档

```py
# 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 访问器适用于周期和时间增量 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](https://github.com/pandas-dev/pandas/issues/7812))

    ```py
    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_localize` 现在接受 `ambiguous` 关键字,允许传递一个布尔数组,指示日期是否属于夏令时,‘NaT’ 用于将过渡时间设置为 NaT,‘infer’ 用于推断夏令时/非夏令时,‘raise’(默认)用于引发 `AmbiguousTimeError`。更多详情请参见 文档 ([GH 7943](https://github.com/pandas-dev/pandas/issues/7943))

+   `DataFrame.tz_localize` 和 `DataFrame.tz_convert` 现在接受可选的 `level` 参数,用于将 MultiIndex 的特定级别本地化([GH 7846](https://github.com/pandas-dev/pandas/issues/7846))

+   `Timestamp.tz_localize` 和 `Timestamp.tz_convert` 现在在错误情况下引发 `TypeError`,而不是 `Exception`([GH 8025](https://github.com/pandas-dev/pandas/issues/8025))

+   插入 Series/DataFrame 中的时序/索引在本地化为 UTC 时将保留 UTC 时区(而不是作为无时区的 `datetime64[ns]`)作为 `object` dtype 显示 ([GH 8411](https://github.com/pandas-dev/pandas/issues/8411))

+   `Timestamp.__repr__` 显示 `dateutil.tz.tzoffset` 信息 ([GH 7907](https://github.com/pandas-dev/pandas/issues/7907))  ### 滚动/扩展矩阵改进

+   `rolling_min()`、`rolling_max()`、`rolling_cov()` 和 `rolling_corr()` 现在在 `len(arg) < min_periods <= window` 时返回具有全部 `NaN` 的对象,而不是引发异常。(这使得所有滚动函数在这个行为上保持一致)。([GH 7766](https://github.com/pandas-dev/pandas/issues/7766))

    在 0.15.0 之前

    ```py
    In [57]: s = pd.Series([10, 11, 12, 13]) 
    ```

    ```py
    In [15]: pd.rolling_min(s, window=10, min_periods=5)
    ValueError: min_periods (5) must be <= window (4) 
    ```

    新行为

    ```py
    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](https://github.com/pandas-dev/pandas/issues/7925), [GH 8269](https://github.com/pandas-dev/pandas/issues/8269))

    先前的行为(注意最终值为 `NaN`):

    ```py
    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])`):

    ```py
    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](https://github.com/pandas-dev/pandas/issues/7618))

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

    0.15.0 之前的行为:

    ```py
    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 
    ```

    新行为

    ```py
    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` 参数(参见 list),因为当 `center=True` 时产生的结果没有太多意义。([GH 7925](https://github.com/pandas-dev/pandas/issues/7925))

+   在 `expanding_cov()` 和 `rolling_cov()` 中添加了可选的 `ddof` 参数。默认值为 `1` 是向后兼容的。([GH 8279](https://github.com/pandas-dev/pandas/issues/8279))

+   将 `ddof` 参数文档化到 `expanding_var()`、`expanding_std()`、`rolling_var()` 和 `rolling_std()`。这些函数对 `ddof` 参数的支持(默认值为 `1`)之前是未文档化的。([GH 8064](https://github.com/pandas-dev/pandas/issues/8064))

+   `ewma()`、`ewmstd()`、`ewmvol()`、`ewmvar()`、`ewmcov()` 和 `ewmcorr()` 现在以与 `rolling_*()` 和 `expanding_*()` 函数相同的方式解释 `min_periods`:如果(在此情况下是扩展的)窗口不包含至少 `min_periods` 个值,则给定的结果条目将为 `NaN`。先前的行为是从第一个非 `NaN` 值开始设置 `min_periods` 条目为 `NaN`。([GH 7977](https://github.com/pandas-dev/pandas/issues/7977))

    之前的行为(注意值从索引 `2` 开始,即在索引 `0`(第一个非空值的索引)之后的 `min_periods` 个位置):

    ```py
    In [59]: s  = pd.Series([1, None, None, None, 2, 3]) 
    ```

    ```py
    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`)非空值的位置):

    ```py
    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()` 现在都有一个可选的 `adjust` 参数,就像 `ewma()` 一样,影响权重的计算方式。`adjust` 的默认值是 `True`,与之前兼容。详细信息请参见指数加权矩函数。([GH 7911](https://github.com/pandas-dev/pandas/issues/7911))

+   `ewma()`、`ewmstd()`、`ewmvol()`、`ewmvar()`、`ewmcov()` 和 `ewmcorr()` 现在都有一个可选的 `ignore_na` 参数。当 `ignore_na=False`(默认情况下)时,在权重计算中会考虑缺失值。当 `ignore_na=True`(复制了 0.15.0 版本之前的行为)时,在权重计算中会忽略缺失值。([GH 7543](https://github.com/pandas-dev/pandas/issues/7543))

    ```py
    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 版本之前的版本不同。要复制在存在缺失值时的权重计算,必须明确指定 `ignore_na=True`。

+   `expanding_cov()`、`expanding_corr()`、`rolling_cov()`、`rolling_cor()`、`ewmcov()` 和 `ewmcorr()` 中的 Bug 返回按名称排序的列,并对非唯一列产生错误;现在处理非唯一列并按原始顺序返回列(除了两个 `pairwise=False` 的 DataFrame 的情况,行为不变) ([GH 7542](https://github.com/pandas-dev/pandas/issues/7542))

+   `rolling_count()` 和 `expanding_*()` 函数中的 Bug 不必要地为零长度数据产生错误消息 ([GH 8056](https://github.com/pandas-dev/pandas/issues/8056))

+   `rolling_apply()` 和 `expanding_apply()` 中的 Bug 将 `min_periods=0` 解释为 `min_periods=1` ([GH 8080](https://github.com/pandas-dev/pandas/issues/8080))

+   `expanding_std()` 和 `expanding_var()` 中的 Bug 对于单个值产生令人困惑的错误消息 ([GH 7900](https://github.com/pandas-dev/pandas/issues/7900))

+   `rolling_std()` 和 `rolling_var()` 中的 Bug 对于单个值产生 `0` 而不是 `NaN` ([GH 7900](https://github.com/pandas-dev/pandas/issues/7900))

+   当 `bias=False`(默认情况下)时,`ewmstd()`、`ewmvol()`、`ewmvar()` 和 `ewmcov()` 中的 Bug 在计算去偏因子时。先前使用了一个基于 `adjust=True`、`ignore_na=True` 和无限观测次数的不正确的常数因子。现在为每个条目使用不同的因子,基于实际权重(类似于通常的 `N/(N-1)` 因子)。特别地,对于单个点,当 `bias=False` 时返回 `NaN` 值,而以前返回 (大约) `0` 的值。

    例如,考虑以下 `ewmvar(..., bias=False)` 的 0.15.0 版本之前的结果,以及相应的去偏因子:

    ```py
    In [60]: s = pd.Series([1., 2., 0., 4.]) 
    ```

    ```py
    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 版本的结果中,条目`0`为`NaN`,并且去偏差因子正在减小(朝向 1.25):

    ```py
    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](https://github.com/pandas-dev/pandas/issues/7912)) ### SQL IO 模块的改进

+   增加了对`to_sql`函数的`chunksize`参数的支持。这允许 DataFrame 分块写入,避免包大小溢出错误([GH 8062](https://github.com/pandas-dev/pandas/issues/8062))。

+   增加了对`read_sql`函数的`chunksize`参数的支持。指定此参数将返回查询结果的迭代器([GH 2908](https://github.com/pandas-dev/pandas/issues/2908))。

+   增加了使用`to_sql`写入`datetime.date`和`datetime.time`对象列的支持([GH 6932](https://github.com/pandas-dev/pandas/issues/6932))。

+   增加了使用`read_sql_table`和`to_sql`指定`schema`读取/写入的支持([GH 7441](https://github.com/pandas-dev/pandas/issues/7441),[GH 7952](https://github.com/pandas-dev/pandas/issues/7952))。例如:

    ```py
    df.to_sql('table', engine, schema='other_schema')  # noqa F821
    pd.read_sql_table('table', engine, schema='other_schema')  # noqa F821 
    ```

+   增加了使用`to_sql`写入`NaN`值的支持([GH 2754](https://github.com/pandas-dev/pandas/issues/2754))。

+   增加了对所有数据库类型使用`to_sql`写入 datetime64 列的支持([GH 7103](https://github.com/pandas-dev/pandas/issues/7103)) ### Series/DataFrame 中的分类

`Categorical`现在可以包含在`Series`和`DataFrame`中,并获得了新的操纵方法。感谢 Jan Schulz 为此 API/实现的贡献。 ([GH 3943](https://github.com/pandas-dev/pandas/issues/3943),[GH 5313](https://github.com/pandas-dev/pandas/issues/5313),[GH 5314](https://github.com/pandas-dev/pandas/issues/5314),[GH 7444](https://github.com/pandas-dev/pandas/issues/7444),[GH 7839](https://github.com/pandas-dev/pandas/issues/7839),[GH 7848](https://github.com/pandas-dev/pandas/issues/7848),[GH 7864](https://github.com/pandas-dev/pandas/issues/7864),[GH 7914](https://github.com/pandas-dev/pandas/issues/7914),[GH 7768](https://github.com/pandas-dev/pandas/issues/7768),[GH 8006](https://github.com/pandas-dev/pandas/issues/8006),[GH 3678](https://github.com/pandas-dev/pandas/issues/3678),[GH 8075](https://github.com/pandas-dev/pandas/issues/8075),[GH 8076](https://github.com/pandas-dev/pandas/issues/8076),[GH 8143](https://github.com/pandas-dev/pandas/issues/8143),[GH 8453](https://github.com/pandas-dev/pandas/issues/8453),[GH 8518](https://github.com/pandas-dev/pandas/issues/8518))。

有关完整文档,请参阅分类介绍和 API 文档。

```py
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_aggpandas.core.factor_agg已被移除。作为替代,构建一个数据框并使用df.groupby(<group>).agg(<func>)

  • 不再支持向Categorical构造函数提供“codes/labels 和 levels”。现在向构造函数提供两个参数被解释为“values 和 levels(现在称为‘categories’)”。请修改您的代码以使用from_codes()构造函数。

  • Categorical.labels属性已更名为Categorical.codes,且为只读。如果要操作 codes,请使用 Categoricals 上的 API 方法之一。

  • Categorical.levels属性已更名为Categorical.categories

TimedeltaIndex/scalar

我们引入了一个新的标量类型Timedelta,它是datetime.timedelta的子类,并且行为类似,但允许与np.timedelta64类型兼容,以及一系列自定义表示、解析和属性。这种类型与datetimesTimestamp的工作方式非常相似。它是该类型的一个很好的 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返回hoursminutesseconds之间的总秒数。相比之下,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 版本更新条目

警告

在 0.15.0 之前,pd.to_timedelta对于类似列表/系列的输入会返���一个Series,对于标量输入会返回一个np.timedelta64。现在,对于类似列表的输入,将返回一个TimedeltaIndex,对于系列输入,将返回一个Series,对于标量输入,将返回一个Timedelta

pd.to_timedelta的参数现在是(arg,unit='ns',box=True,coerce=False),之前是(arg,box=True,unit='ns'),因为这样更合乎逻辑。

构建一个标量

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')] 
  • Series进行迭代,例如list(Series(...))timedelta64[ns],在 v0.15.0 之前返回的是每个元素的np.timedelta64。现在将会包装在Timedelta中。

内存使用

实现了查找 DataFrame 内存使用量的方法。更多信息请参阅 FAQ。(GH 6852

一个新的显示选项display.memory_usage(请参阅选项和设置)设置了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), datetime64ns, float64(1), int64(1), object(1), timedelta64ns
memory usage: 288.2+ KB 

此外,memory_usage()是一个 dataframe 对象可用的方法,它返回每列的内存使用情况。

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 访问器

Series已经获得了一个访问器,以简洁地返回Series的日期时间属性,如果它是一个日期时间/期间类型的 Series。(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
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] 

时区处理改进

  • 对于 tz-aware TimestampDatetimeIndextz_localize(None)现在会移除持有本地时间的时区,以前这会导致ExceptionTypeError。(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_localize现在接受ambiguous关键字,它允许传递一个布尔数组,指示日期是否属于夏令时,‘NaT’表示将过渡时间设置为 NaT,‘infer’表示推断 DST/non-DST,‘raise’(默认)表示引发AmbiguousTimeError。请参阅文档了解更多详情(GH 7943

  • DataFrame.tz_localizeDataFrame.tz_convert现在接受可选的level参数,用于本地化多级索引的特定级别(GH 7846

  • Timestamp.tz_localizeTimestamp.tz_convert现在在错误情况下会引发TypeError,而不是ExceptionGH 8025

  • 将插入到 Series/DataFrame 中的 UTC 本地化的时间序列/索引将保留 UTC 时区(而不是作为object dtype 的简单`datetime64[ns])。(GH 8411)

  • Timestamp.__repr__显示dateutil.tz.tzoffset信息。(GH 7907)

滚动/扩展时刻的改进

  • len(arg) < min_periods <= window时,rolling_min()rolling_max()rolling_cov()rolling_corr()现在返回所有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)/2NaN值(或者在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() 现在对 min_periods 的解释与 rolling_*()expanding_*() 函数相同:如果(在这种情况下是扩展窗口)窗口中的值至少不包含 min_periods 个值,则给定的结果条目将为 NaN。先前的行为是从第一个非 NaN 值开始将 min_periods 条目设置为 NaN。(GH 7977)

    先前的行为(请注意,值从索引 2 开始,这是索引 0(第一个非空值的索引)后的 min_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)非空值的位置):

    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() 现在有一个可选的 adjust 参数,就像 ewma() 一样,影响权重的计算方式。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() 中的 Bug,返回以名称排序的列和对于非唯一列产生错误的结果;现在处理非唯一列并按原始顺序返回列(除了两个 DataFrame 的情况下,pairwise=False,其行为不变)(GH 7542)

  • rolling_count()expanding_*() 函数中的 Bug,在长度为零的数据上不必要地产生错误消息 (GH 8056)

  • rolling_apply()expanding_apply() 中的 Bug,将 min_periods=0 解释为 min_periods=1 (GH 8080)

  • expanding_std()expanding_var() 在只有一个数值时会产生令人困惑的错误消息的 Bug (GH 7900)

  • rolling_std()rolling_var() 在只有一个数值时产生 0 而不是 NaN 的 Bug (GH 7900)

  • bias=False(默认)时,ewmstd()ewmvol()ewmvar()ewmcov()计算去偏因子时存在错误。先前使用了一个错误的常数因子,基于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_sql写入datetime.datedatetime.time对象列的支持 (GH 6932)。

  • 增加了对使用read_sql_tableto_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_sql写入NaN值的支持 (GH 2754)。

  • 增加了对使用to_sql写入 datetime64 列的所有数据库类型的支持 (GH 7103)。

不向后兼容的 API 更改

破坏性变化

Categorical相关的 API 更改(有关更多详情,请参见此处):

  • 两个参数的Categorical构造函数从“codes/labels 和 levels”更改为“values 和 levels(现在称为‘categories’)”。这可能会导致细微的错误。如果您直接使用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,对于标量输入返回np.timedelta64。现在,对于类似列表的输入,将返回TimedeltaIndex,对于序列输入,将返回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] 
    

    在以前的版本中,这两个构造之间存在差异:

    • 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 
    

    此外,如果在具有列表类索引器的 MultiIndex 中未找到值,则.loc将引发异常:

    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" 
    
  • 现在在选择“空”值时,将考虑 dtype 分配给NoneGH 7941)。

    以前,在数字容器中将值分配给None会将 dtype 更改为 object(或者根据调用而出错)。现在使用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

    对于对象容器,我们现在保留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 
    

    0.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_csvread_table的基于 C 和 Python 的引擎都忽略输入中的空行以及填充了空格的行,只要sep不是空格。这是一个可以通过关键字参数skip_blank_lines来控制的 API 更改。参见文档(GH 4466

  • 插入到 Series/DataFrame 中的 UTC 本地化的时间序列/索引将保留 UTC 时区,并插入为object dtype 而不是转换为不带时区的datetime64[ns]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 列。

    将列分配给现有 DataFrame 的行为df['a'] = i保持不变(这已经返回了一个带有时区的object列)。

  • 当向stack()传递多个级别时,如果级别不全是级别名称或全是级别编号,则现在会引发ValueErrorGH 7660)。参见通过堆叠和取消堆叠进行重塑。

  • 在使用‘fixed’格式时,如果df具有非唯一列,则在df.to_hdf中引发ValueError,因为生成的文件将损坏(GH 7761)。

  • 当使用链式赋值在切片的混合 dtype DataFrame 上设置值时,根据选项mode.chained_assignment,将发出SettingWithCopy的警告/错误(GH 7845GH 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 
    
  • mergeDataFrame.mergeordered_merge现在返回与left参数相同的类型(GH 7737)。

  • 之前对混合 dtype 的 DataFrame 进行扩展时的行为与.append不同,后者会保留 dtype(相关问题GH 2578GH 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。之前会创建一个新的空文件,并引发KeyErrorGH 7715)。

  • DataFrame.info()现在在输出结束时会加上一个换行符(GH 8114)。

  • 现在连接空对象将引发ValueError而不是裸的Exception

  • 合并错误现在将是ValueError的子类,而不是裸的ExceptionGH 8501)。

  • DataFrame.plotSeries.plot的关键字现在具有一致的顺序(GH 8037) ### 内部重构

在 0.15.0 版本中,Index在内部已经被重构,不再是ndarray的子类,而是PandasObject的子类,与其他 pandas 对象类似。这个改变使得非常容易进行子类化和创建新的索引类型。这应该是一个透明的改变,只有非常有限的 API 影响 (GH 5080, GH 7439, GH 7796, GH 8024, GH 8367, GH 7997, GH 8522):

  • 您可能需要使用pd.read_pickle而不是pickle.load来解除 pickle pandas 版本< 0.15.0 的 pickle。参见 pickle 文档

  • 使用PeriodIndex绘图时,matplotlib 内部轴现在将是Period的数组,而不是PeriodIndex(类似于DatetimeIndex现在传递datetimes数组的方式)

  • MultiIndexes 现在将与其他 pandas 对象类似地引发异常,关于真值测试,请参见这里 (GH 7897).

  • 直接使用 matplotlib 的plot函数绘制 DatetimeIndex 时,轴标签将不再格式化为日期,而是整数(datetime64的内部表示)。更新 这在 0.15.1 中已修复,参见这里。 ### 弃用

  • Categoricallabelslevels属性已被弃用,并更名为codescategories

  • pd.DataFrame.to_dictouttype参数已被弃用,推荐使用orient。(GH 7840)

  • convert_dummies方法已被弃用,推荐使用get_dummies (GH 8140)

  • tz_localize中的infer_dst参数将被弃用,推荐使用ambiguous以更灵活地处理夏令时转换。将infer_dst=True替换为ambiguous='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 7762GH 7032)。 ### 删除之前版本的弃用/更改

  • 删除DataFrame.delevel方法,改用DataFrame.reset_index ### 重大变更

Categorical相关的 API 更改(有关更多详细信息,请参见此处):

  • Categorical构造函数的两个参数从“codes/labels 和 levels”更改为“值和 levels(现在称为‘categories’)”。这可能会导致微妙的错误。如果直接使用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,对于标量输入会返回一个np.timedelta64。现在,对于类似列表的输入,将返回一个TimedeltaIndex,对于系列输入,将返回一个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] 
    

    在之前的版本中,这两种结构有区别:

    • df.loc[[3]]会返回由 3 重新索引的数据框(所有值为np.nan)。

    • df.loc[[3],:]会引发KeyError

    当使用类似列表的索引器和.loc时,至少要找到 1 个索引器,否则会引发KeyErrorGH 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 
    

    此外,如果在具有类似列表的索引器的 MultiIndex 中找不到值,.loc会引发异常:

    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" 
    
  • 当选择“空”值时,现在会考虑 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现在在日期时间容器中也类似使用。

    对于对象容器��我们现在保留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 8511GH 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 
    
  • 使基于 C 和 Python 的read_csvread_table引擎忽略输入中的空行以及填充有空格的行,只要sep不是空格。这是一个可以通过关键字参数skip_blank_lines控制的 API 更改。请参阅文档 (GH 4466)

  • 将插入 Series/DataFrame 的时间序列/索引本地化为 UTC 时,将保留 UTC 时区,并插入为object类型,而不是转换为一个无时区的datetime64[ns]GH 8411)。

  • 在从字典构建 DataFrame 时,传递具有未保留的时区的时区的DatetimeIndex的 bug([GH 7822](https://github.com/pandas-dev/pandas/issues/7822)

    在之前的版本中,这将丢弃时区,现在保留时区,但会给出一个object类型的列:

    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 列。

    将列分配给现有 DataFrame 的行为为df['a'] = i保持不变(这已经返回了一个带有时区的object列)。

  • 当向stack()传递多个级别时,如果级别不全是级别名称或全是级别数字,则现在会引发ValueErrorGH 7660)。请参阅通过堆叠和取消堆叠进行重塑。

  • 在使用‘fixed’格式的df.to_hdf中,如果df具有非唯一列,则会引发ValueError,因为生成的文件将损坏(GH 7761

  • 使用链式赋值设置切片的混合 dtype DataFrame 上设置值时,SettingWithCopy会根据选项mode.chained_assignment发出警告/提醒。(GH 7845GH 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 
    
  • mergeDataFrame.mergeordered_merge现在返回与left参数相同的类型(GH 7737)。

  • 以前,使用混合 dtype 框架进行扩展的行为与.append不同,后者将保留 dtype(相关GH 2578GH 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)

  • 连接没有对象现在会引发 ValueError 而不是裸露的 Exception

  • 合并错误现在将是 ValueError 的子类,而不是原始的 Exception (GH 8501)

  • DataFrame.plotSeries.plot 的关键字现在具有一致的顺序 (GH 8037)

内部重构

在 0.15.0 版本中,Index 在内部已经被重构,不再是 ndarray 的子类,而是 PandasObject 的子类,与 pandas 的其他对象类似。这个改变使得非常容易创建新的索引类型。这应该是一个透明的改变,只有非常有限的 API 影响 (GH 5080, GH 7439, GH 7796, GH 8024, GH 8367, GH 7997, GH 8522):

  • 您可能需要使用 pd.read_pickle 而不是 pickle.load 来解除序列化 pandas 版本 < 0.15.0 的 pickle。请参阅 pickle 文档

  • 当使用 PeriodIndex 绘图时,matplotlib 内部的坐标轴现在将是 Period 的数组,而不是 PeriodIndex(这类似于 DatetimeIndex 现在传递 datetimes 数组的方式)

  • MultiIndexes 现在将与其他 pandas 对象类似地引发关于真值测试的异常,请参见 这里 (GH 7897).

  • 直接使用 matplotlib 的 plot 函数绘制 DatetimeIndex 时,轴标签将不再格式化为日期,而是整数(datetime64 的内部表示)。 更新 这在 0.15.1 版本中已修复,参见 这里.

弃用

  • Categoricallabelslevels 属性已被弃用,并更名为 codescategories.

  • pd.DataFrame.to_dictouttype 参数已被弃用,推荐使用 orient。 (GH 7840)

  • convert_dummies 方法已被弃用,推荐使用 get_dummies (GH 8140)

  • tz_localize 中,infer_dst 参数将被弃用,以支持 ambiguous 参数,以便更灵活地处理 DST 过渡。将 infer_dst=True 替换为 ambiguous='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_stataStataWriter 会检查字符串长度,以确保与 dta 文件中的限制相容,其中固定宽度字符串必须包含 244 个或更少字符。尝试写入超过 244 个字符的字符串的 Stata dta 文件会引发 ValueError。(GH 7858)

  • read_stataStataReader 可以通过将 convert_missing 参数设置为 True 将缺失数据信息导入到 DataFrame 中。在使用此选项时,缺失值将作为 StataMissingValue 对象返回,包含缺失值的列将具有 object 数据类型。 (GH 8045)

绘图函数的增强功能:

  • DataFrame.plot 中添加了 layout 关键字。你可以传递一个元组 (rows, columns),其中之一可以为 -1,以自动推断。(GH 6667, GH 8071)

  • 允许将多个轴传递给 DataFrame.plot, histboxplot (GH 5353, GH 6970, GH 7069)

  • DataFrame.plot中的kind='scatter'添加了对ccolormapcolorbar参数的支持 (GH 7780)

  • DataFrame.plot中的直方图,使用kind='hist' (GH 7809),参见文档。

  • DataFrame.plot中的箱线图,使用kind='box' (GH 7998),参见文档。

其他:

  • read_csv现在有一个关键参数float_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] 
    
  • PeriodIndex支持resolutionDatetimeIndex相同 (GH 7708)

  • pandas.tseries.holiday已经添加了对额外节假日和观察节假日方式的支持 (GH 7070)

  • pandas.tseries.holiday.Holiday现在在 Python3 中支持偏移列表 (GH 7070)

  • pandas.tseries.holiday.Holiday现在支持一个days_of_week参数 (GH 7070)

  • GroupBy.nth()现在支持选择多个第 n 个值 (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] 
    
  • PeriodPeriodIndex支持与timedelta类似的加法/减法 (GH 7966)

    如果Period频率是DHTSLUN,则如果结果具有相同的频率,则可以添加类似于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]') 
    
  • 添加与openpyxl版本>= 2.0 的实验性兼容性。DataFrame.to_excel方法的engine关键字现在识别openpyxl1openpyxl2,分别明确要求 openpyxl v1 和 v2,如果请求的版本不可用,则失败。openpyxl引擎现在是一个元引擎,自动使用已安装的 openpyxl 版本(GH 7177

  • DataFrame.fillna现在可以接受DataFrame作为填充值(GH 8377

  • 将多个级别传递给stack()现在可以在传递多个级别编号时正常工作(GH 7660)。请参阅通过堆叠和取消堆叠进行重塑。

  • set_names()set_labels()set_levels()方法现在接受一个可选的level关键字参数,以修改多级索引的特定级别。此外,当在Index上操作或在MultiIndex的特定级别上操作时,set_names()现在接受标量字符串值(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 7892GH 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) 
    
  • Index现在支持duplicateddrop_duplicatesGH 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.concat中添加copy=True参数,以便通过完整块进行传递(GH 8252

  • 增加对 numpy 1.8+数据类型(bool_int_float_string_)的支持,以便转换为 R dataframe(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

  • 在组别.agg.apply中的性能改进,其中内置的 max/min 未映射到 numpy/cython 化的版本(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_csv中存在错误,其中squeeze=True会返回一个视图(GH 8217

  • 在某些情况下检查read_sql中的表名存在错误(GH 7826

  • DataFrame.groupby中存在错误,当指定频率时,Grouper不识别级别(GH 7885

  • 在 DataFrame 保存到 SQL 表时,MultiIndex 的 dtype 混淆引发错误(GH 8021

  • Series中存在错误,使用 float 和整数操作数 dtype 进行 0-除法(GH 7785

  • Series.astype("unicode")中存在错误,未正确调用值上的unicodeGH 7758

  • DataFrame.as_matrix()中存在错误,混合datetime64[ns]timedelta64[ns] dtype 时(GH 7778

  • 在选择DatetimeIndex时,HDFStore.select_column()不保留 UTC 时区信息时存在错误(GH 7777

  • to_datetime中存在错误,当指定format='%Y%m%d'coerce=True时,之前会返回对象数组(而不是一个强制转换的时间序列,带有NaT)(GH 7930

  • DatetimeIndexPeriodIndex中的就地加法和减法引起与正常结果不同的错误(GH 6527

  • 在使用PeriodIndex添加和减去PeriodIndex时引发TypeError错误(GH 7741

  • combine_first中存在错误,带有PeriodIndex数据引发TypeErrorGH 3367

  • 修复了具有缺失索引器的 MultiIndex 切片中的错误(GH 7866

  • 在各种边缘情况下的 MultiIndex 切片中存在错误(GH 8132

  • 使用非标量类型对象进行 MultiIndex 索引时的回归 bug (GH 7914)

  • Timestamp 比较中的一个 bug,使用 ==int64 数据类型 (GH 8058)

  • 包含 DateOffset 的 pickle 可能在内部引用 normalize 属性时引发 AttributeError (GH 7748)

  • 使用 major_xs 且传递 copy=False 时的 Panel 中的 bug(由于缺少 warnings 而导致弃用警告失败) (GH 8152)

  • pickle 反序列化中的一个 bug,对于 pre-0.14.1 容器失败的情况,尝试避免匹配块和管理器项时的歧义,当只有一个块时没有歧义 (GH 7794)

  • PeriodIndex 放入 Series 中的一��� bug 会转换为 int64 数据类型,而不是 Periodsobject (GH 7932)

  • 在传递 where 参数时,HDFStore 迭代中的一个 bug (GH 8014)

  • 使用传递的非排序键进行 DataFrameGroupby.transform 时的 bug (GH 8046, GH 8430)

  • 重复时间序列线和区域图绘制中的一个 bug 可能导致 ValueError 或不正确的类型 (GH 7733)

  • MultiIndex 推断中的一个 bug,使用 datetime.date 输入 (GH 7888)

  • get 中,IndexError 不会导致返回默认值的 bug (GH 7725)

  • offsets.applyrollforwardrollback 中的一个 bug 可能会重置纳秒 (GH 7697)

  • offsets.applyrollforwardrollback 中的一个 bug,如果 Timestamp 具有 dateutil tzinfo,则可能引发 AttributeError (GH 7697)

  • 使用 Float64Index 对 MultiIndex 框架进行排序中的一个 bug (GH 8017)

  • 不一致的面板设置项中的一个 bug,右手边是 DataFrame 用于对齐 (GH 7763)

  • is_superperiodis_subperiod 中的一个 bug 无法处理高于 S 的频率 (GH 7760, GH 7772, GH 7803)

  • 在 32 位平台上使用 Series.shift 中的 bug (GH 8129)

  • PeriodIndex.unique 返回 int64 np.ndarray 中的一个 bug (GH 7540)

  • groupby.apply 中的一个 bug,函数中的一个不影响的变异 (GH 8467)

  • MultiIndex包含PeriodIndex或带有时区的DatetimeIndex时,DataFrame.reset_index存在错误引发ValueErrorGH 7746GH 7793

  • subplots=True时,DataFrame.plot可能会绘制不必要的次要 xticks 和 yticks(GH 7801

  • StataReader中,由于 Stata 文档和实现之间的差异,117 个文件中未读取变量标签(GH 7816

  • StataReader中,字符串总是转换为 244 个字符的固定宽度,而不考虑底层字符串大小(GH 7858

  • DataFrame.plotSeries.plot可能会忽略rotfontsize关键字(GH 7844

  • DatetimeIndex.value_counts不保留时区(GH 7735

  • PeriodIndex.value_counts导致Int64IndexGH 7735

  • 在对索引进行左连接且存在多个匹配项时,DataFrame.join存在错误(GH 5391

  • GroupBy.transform()中,具有不保留索引的转换的整数组错误地被截断(GH 7972

  • groupby中,没有名称属性的可调用对象会走错路径,生成DataFrame而不是Series的错误(GH 7929

  • 当 DataFrame 分组列重复时,groupby错误消息中存在错误(GH 7511

  • read_html中,infer_types参数强制错误地转换日期类型(GH 7762GH 7032

  • 具有被过滤以不包括第一项的索引的Series.str.cat存在错误([GH 7857](https://github.com/pandas-dev/pandas/issues/7857)

  • Timestamp无法从字符串中解析nanosecondGH 7878

  • 字符串偏移和tz结果不正确时,Timestamp存在错误(GH 7833

  • tslib.tz_converttslib.tz_convert_single中可能返回不同结果的错误(GH 7798

  • DatetimeIndex.intersection中,具有时区的非重叠时间戳引发IndexErrorGH 7880

  • TimeOps和非唯一索引对齐时存在错误(GH 8363

  • GroupBy.filter()中存在的错误,快速路径与慢速路径使过滤器返回一个非标量值,看起来是有效的,但实际上不是(GH 7870)。

  • date_range()/DatetimeIndex()中存在的错误,当时区从输入日期推断出来时,穿过夏令时边界时返回不正确的时间(GH 7835GH 7901)。

  • to_excel()中存在的错误,正无穷被加上了负号,而负无穷没有(GH 7949)。

  • 在区域图中存在的错误,当stacked=True时,图例绘制的透明度不正确(GH 8027)。

  • 使用np.timedelta64进行PeriodPeriodIndex的加法/减法会导致内部表示错误(GH 7740)。

  • Holiday中存在的错误,没有偏移或观察(GH 7987)。

  • DataFrame.to_latex格式化存在的错误,当列或索引是MultiIndex时(GH 7982)。

  • 在夏令时周围的DateOffset中存在的错误,产生意外的结果(GH 5175)。

  • DataFrame.shift中存在的错误,空列将在 numpy 1.7 上抛出ZeroDivisionErrorGH 8019)。

  • 安装中存在的错误,html_encoding/*.html未被安装,因此一些测试未能正确运行(GH 7927)。

  • read_html中存在的错误,未在_read中测试bytes对象(GH 7927)。

  • DataFrame.stack()中存在的错误,当列级别之一是日期时(GH 8039)。

  • 在使用DataFrame广播 numpy 标量时存在的错误(GH 8116)。

  • pivot_table在使用无名称的indexcolumns时出现了KeyError错误(GH 8103)。

  • DataFrame.plot(kind='scatter')中存在的错误,当颜色由c关键字指定时,绘制点和误差条的颜色不同(GH 8081)。

  • Float64Index中存在的错误,iatat未经过测试并且失败了(GH 8092)。

  • DataFrame.boxplot()中存在的错误,当生成多个坐标轴时,y 轴限制未正确设置(GH 7528GH 5517)。

  • read_csv中存在的错误,当给定自定义行终止符或delim_whitespace=True时,行注释未能正确处理(GH 8122)。

  • read_html 中的一个 bug,空表格导致 StopIterationGH 7575

  • 在设置同一 dtype 块中的列时转换中的一个 bug(GH 7704

  • GroupBy 中访问组时,原始分组器为元组时的一个 bug(GH 8121)。

  • .at 中的一个 bug,会在非整数索引上接受整数索引器并执行回退(GH 7814

  • kde 绘图和 NaNs 中的一个 bug(GH 8182

  • GroupBy.count 中的一个 bug,float32 数据类型中 nan 值未被排除(GH 8169)。

  • 堆叠条形图和 NaNs 中的一个 bug(GH 8175)。

  • resample 中的一个 bug,非均匀可除的偏移量(例如‘7s’)(GH 8371

  • 插值方法中的一个 bug,当不需要插值时,使用 limit 关键字时出��问题(GH 7173)。

  • DataFrame.to_string() 中忽略了 header=Falsecol_space 的 bug(GH 8230)。

  • DatetimeIndex.asof 中的一个 bug,错误匹配部分字符串并返回错误日期(GH 8245)。

  • 绘图方法中的一个 bug,修改了全局 matplotlib rcParams(GH 8242)。

  • DataFrame.__setitem__ 中的一个 bug,将 dataframe 列设置为稀疏数组时出错(GH 8131

  • 当整个列为空时,Dataframe.boxplot() 失败的一个 bug(GH 8181)。

  • radviz 可视化中变量混乱的一个 bug(GH 8199)。

  • 插值方法中的一个 bug,当不需要插值时,使用 limit 关键字时出现问题(GH 7173)。

  • DataFrame.to_string() 中忽略了 header=Falsecol_space 的 bug(GH 8230)。

  • to_clipboard 中的一个 bug,会截断长列数据(GH 8305

  • DataFrame 终端显示中的一个 bug:将 max_column/max_rows 设置为零时,未触发自动调整 df 以适应终端宽度/高度(GH 7180)。

  • OLS 中的一个 bug,使用“cluster”和“nw_lags”参数运行时无法正确工作,但也不会抛出错误(GH 5884)。

  • DataFrame.dropna 中的一个 bug,将 subset 参数中不存在的列解释为“最后一列”(GH 8303

  • 在非单调非唯一索引上的 Index.intersection 中出现的错误 (GH 8362).

  • 掩码系列赋值中的错误,类型不匹配会导致对齐中断 (GH 8387)

  • NDFrame.equals 中的错误,dtype=object 时给出错误的负面结果 (GH 8437)

  • 在索引器赋值中出现的错误,类型多样性会导致对齐中断 (GH 8258)

  • NDFrame.loc 索引中的错误,当行/列名称丢失时,如果目标是列表/ndarray (GH 6552)

  • NDFrame.loc 索引中的回归,当行/列转换为 Float64Index 时,如果目标为空列表/ndarray,则出现错误 (GH 7774)

  • Series 中的错误,允许使用 DataFrame 对其进行索引,结果出乎意料。不再允许这种索引 (GH 8444)

  • 在具有 MultiIndex 列的 DataFrame 的项目赋值中出现的错误,其中右侧列未对齐 (GH 7655)

  • 抑制 NumPy 生成的 FutureWarning,当包含 NaN 的对象数组进行相等比较时 (GH 7065)

  • DataFrame.eval() 中的一个错误,not 运算符 (~) 的 dtype 未能正确推断为 bool

贡献者

总共有 80 人为此版本贡献了补丁。名字后面带有“+”的人第一次贡献了补丁。

  • Aaron Schumacher +

  • Adam Greenhall

  • Andy Hayden

  • Anthony O’Brien +

  • Artemy Kolchinsky +

  • Ben Schiller +

  • Benedikt Sauer

  • Benjamin Thyreau +

  • BorisVerk +

  • Chris Reynolds +

  • Chris Stoafer +

  • DSM

  • Dav Clark +

  • FragLegs +

  • German Gomez-Herrero +

  • Hsiaoming Yang +

  • Huan Li +

  • Hyungtae Kim +

  • Isaac Slavitt +

  • Jacob Schaer

  • Jacob Wasserman +

  • Jan Schulz

  • Jeff Reback

  • Jeff Tratner

  • Jesse Farnham +

  • Joe Bradish +

  • Joerg Rittinger +

  • John W. O’Brien

  • Joris Van den Bossche

  • Kevin Sheppard

  • Kyle Meyer

  • Max Chang +

  • Michael Mueller

  • Michael W Schatzow +

  • Mike Kelly

  • Mortada Mehyar

  • Nathan Sanders +

  • Nathan Typanski +

  • Paul Masurel +

  • Phillip Cloud

  • Pietro Battiston

  • RenzoBertocchi +

  • Ross Petchler +

  • Shahul Hameed +

  • Shashank Agarwal +

  • Stephan Hoyer

  • Tom Augspurger

  • TomAugspurger

  • Tony Lorenzo +

  • Wes Turner

  • Wilfred Hughes +

  • Yevgeniy Grechka +

  • Yoshiki Vázquez Baeza +

  • behzad nouri +

  • benjamin

  • bjonen +

  • dlovell +

  • dsm054

  • hunterowens +

  • immerrr

  • ischwabacher

  • jmorris0x0 +

  • jnmclarty +

  • jreback

  • klonuo +

  • lexual

  • mcjcode +

  • mtrbean +

  • onesandzeroes

  • rockg

  • seth-p

  • sinhrks

  • someben +

  • stahlous +

  • stas-sl +

  • thatneat +

  • tom-alcorn +

  • unknown

  • unutbu

  • zachcp +

posted @ 2024-06-26 10:35  绝不原创的飞龙  阅读(1)  评论(0编辑  收藏  举报