版本 0.18.0(2016年3月13日)#

这是继 0.17.1 之后的一个主要版本,包含少量的 API 变更、几个新特性、增强功能、性能改进以及大量的 bug 修复。我们建议所有用户升级到此版本。

警告

pandas >= 0.18.0 不再兼容 Python 2.6 和 3.3 版本(GH 7718, GH 11273

警告

由于存在一些 buggy 的行为,numexpr 版本 2.4.4 现在将显示警告,并且不再用作 pandas 的计算后端。这不影响其他版本(>= 2.1 和 >= 2.4.6)。(GH 12489

主要亮点包括

  • 移动和扩展窗口函数现在是 Series 和 DataFrame 的方法,类似于 .groupby,详情请参见此处

  • 增加了对 RangeIndex 的支持,它是 Int64Index 的一种特殊形式,用于节省内存,详情请参见此处

  • .resample 方法进行了 API 破坏性修改,使其更像 .groupby,详情请参见此处

  • 移除了对使用浮点数进行位置索引的支持,此功能自 0.14.0 版本起已被弃用。现在这将引发 TypeError,详情请参见此处

  • 添加了 .to_xarray() 函数,用于与 xarray 包兼容,详情请参见此处

  • 更改了 read_sas 函数,增加了读取 sas7bdat 文件的功能,详情请参见此处

  • 添加了 .str.extractall() 方法,并对 .str.extract() 方法.str.cat() 方法进行了 API 更改。

  • 顶层 nose 测试运行器 pd.test() 已可用(GH 4327)。

在更新之前,请检查 API 变更弃用功能

新特性#

窗口函数现在是方法#

窗口函数已被重构为 Series/DataFrame 对象上的方法,而不再是顶层函数(顶层函数现已弃用)。这使得这些窗口类型函数拥有与 .groupby 类似的 API。完整文档请参见此处GH 11603, GH 12373)。

In [1]: np.random.seed(1234)

In [2]: df = pd.DataFrame({'A': range(10), 'B': np.random.randn(10)})

In [3]: df
Out[3]: 
   A         B
0  0  0.471435
1  1 -1.190976
2  2  1.432707
3  3 -0.312652
4  4 -0.720589
5  5  0.887163
6  6  0.859588
7  7 -0.636524
8  8  0.015696
9  9 -2.242685

[10 rows x 2 columns]

之前行为

In [8]: pd.rolling_mean(df, window=3)
        FutureWarning: pd.rolling_mean is deprecated for DataFrame and will be removed in a future version, replace with
                       DataFrame.rolling(window=3,center=False).mean()
Out[8]:
    A         B
0 NaN       NaN
1 NaN       NaN
2   1  0.237722
3   2 -0.023640
4   3  0.133155
5   4 -0.048693
6   5  0.342054
7   6  0.370076
8   7  0.079587
9   8 -0.954504

新行为

In [4]: r = df.rolling(window=3)

这些显示了描述性的 repr

In [5]: r
Out[5]: Rolling [window=3,center=False,axis=0,method=single]

并支持可用方法和属性的 tab 补全。

In [9]: r.<TAB>  # noqa E225, E999
r.A           r.agg         r.apply       r.count       r.exclusions  r.max         r.median      r.name        r.skew        r.sum
r.B           r.aggregate   r.corr        r.cov         r.kurt        r.mean        r.min         r.quantile    r.std         r.var

这些方法直接作用于 Rolling 对象本身

In [6]: r.mean()
Out[6]: 
     A         B
0  NaN       NaN
1  NaN       NaN
2  1.0  0.237722
3  2.0 -0.023640
4  3.0  0.133155
5  4.0 -0.048693
6  5.0  0.342054
7  6.0  0.370076
8  7.0  0.079587
9  8.0 -0.954504

[10 rows x 2 columns]

它们提供 getitem 访问器

In [7]: r['A'].mean()
Out[7]: 
0    NaN
1    NaN
2    1.0
3    2.0
4    3.0
5    4.0
6    5.0
7    6.0
8    7.0
9    8.0
Name: A, Length: 10, dtype: float64

并支持多种聚合

In [8]: r.agg({'A': ['mean', 'std'],
   ...:        'B': ['mean', 'std']})
   ...: 
Out[8]: 
     A              B          
  mean  std      mean       std
0  NaN  NaN       NaN       NaN
1  NaN  NaN       NaN       NaN
2  1.0  1.0  0.237722  1.327364
3  2.0  1.0 -0.023640  1.335505
4  3.0  1.0  0.133155  1.143778
5  4.0  1.0 -0.048693  0.835747
6  5.0  1.0  0.342054  0.920379
7  6.0  1.0  0.370076  0.871850
8  7.0  1.0  0.079587  0.750099
9  8.0  1.0 -0.954504  1.162285

[10 rows x 4 columns]

rename 的变更#

Series.renameNDFrame.rename_axis 现在除了改变标签的旧有行为外,还可以接受标量或列表类参数来改变 Series 或轴的*名称*(name)。(GH 9494, GH 11965)

In [9]: s = pd.Series(np.random.randn(5))

In [10]: s.rename('newname')
Out[10]: 
0    1.150036
1    0.991946
2    0.953324
3   -2.021255
4   -0.334077
Name: newname, Length: 5, dtype: float64
In [11]: df = pd.DataFrame(np.random.randn(5, 2))

In [12]: (df.rename_axis("indexname")
   ....:    .rename_axis("columns_name", axis="columns"))
   ....: 
Out[12]: 
columns_name         0         1
indexname                       
0             0.002118  0.405453
1             0.289092  1.321158
2            -1.546906 -0.202646
3            -0.655969  0.193421
4             0.553439  1.318152

[5 rows x 2 columns]

新功能在方法链中运行良好。以前,这些方法只接受将*标签*(label)映射到新标签的函数或字典。对于函数或字典类的值,此功能仍像以前一样工作。

Range Index#

Int64Index 的子类中添加了一个 RangeIndex,以支持常见用例中的内存节省替代方案。它的实现类似于 python 的 range 对象(python 2 中的 xrange),因为它只存储索引的 start、stop 和 step 值。它将透明地与用户 API 交互,并在需要时转换为 Int64Index

现在,这将成为 NDFrame 对象的默认构建索引,而不是以前的 Int64Index。(GH 939, GH 12070, GH 12071, GH 12109, GH 12888)

之前行为

In [3]: s = pd.Series(range(1000))

In [4]: s.index
Out[4]:
Int64Index([  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
            ...
            990, 991, 992, 993, 994, 995, 996, 997, 998, 999], dtype='int64', length=1000)

In [6]: s.index.nbytes
Out[6]: 8000

新行为

In [13]: s = pd.Series(range(1000))

In [14]: s.index
Out[14]: RangeIndex(start=0, stop=1000, step=1)

In [15]: s.index.nbytes
Out[15]: 128

str.extract 的变更#

.str.extract 方法接受一个带有捕获组的正则表达式,在每个主题字符串中找到第一个匹配项,并返回捕获组的内容(GH 11386)。

在 v0.18.0 中,向 extract 添加了 expand 参数。

  • expand=False:根据主题和正则表达式模式,返回 SeriesIndexDataFrame(与 0.18.0 版本之前的行为相同)。

  • expand=True:它始终返回一个 DataFrame,这从用户的角度来看更加一致且不易混淆。

目前默认值为 expand=None,这将生成 FutureWarning 并使用 expand=False。为避免此警告,请明确指定 expand

In [1]: pd.Series(['a1', 'b2', 'c3']).str.extract(r'[ab](\d)', expand=None)
FutureWarning: currently extract(expand=None) means expand=False (return Index/Series/DataFrame)
but in a future version of pandas this will be changed to expand=True (return DataFrame)

Out[1]:
0      1
1      2
2    NaN
dtype: object

如果 expand=False,提取一个带有一个分组的正则表达式将返回一个 Series。

In [16]: pd.Series(['a1', 'b2', 'c3']).str.extract(r'[ab](\d)', expand=False)
Out[16]: 
0      1
1      2
2    NaN
Length: 3, dtype: object

如果 expand=True,它将返回一个只有一列的 DataFrame

In [17]: pd.Series(['a1', 'b2', 'c3']).str.extract(r'[ab](\d)', expand=True)
Out[17]: 
     0
0    1
1    2
2  NaN

[3 rows x 1 columns]

如果 expand=False,对一个带有恰好一个捕获组的正则表达式应用于 Index 时将返回一个 Index

In [18]: s = pd.Series(["a1", "b2", "c3"], ["A11", "B22", "C33"])

In [19]: s.index
Out[19]: Index(['A11', 'B22', 'C33'], dtype='object')

In [20]: s.index.str.extract("(?P<letter>[a-zA-Z])", expand=False)
Out[20]: Index(['A', 'B', 'C'], dtype='object', name='letter')

如果 expand=True,它将返回一个只有一列的 DataFrame

In [21]: s.index.str.extract("(?P<letter>[a-zA-Z])", expand=True)
Out[21]: 
  letter
0      A
1      B
2      C

[3 rows x 1 columns]

如果 expand=False,对一个带有多个捕获组的正则表达式应用于 Index 时将引发 ValueError

>>> s.index.str.extract("(?P<letter>[a-zA-Z])([0-9]+)", expand=False)
ValueError: only one regex group is supported with Index

如果 expand=True,它将返回一个 DataFrame

In [22]: s.index.str.extract("(?P<letter>[a-zA-Z])([0-9]+)", expand=True)
Out[22]: 
  letter   1
0      A  11
1      B  22
2      C  33

[3 rows x 2 columns]

总之,extract(expand=True) 始终返回一个 DataFrame,其中每一行对应一个主题字符串,每一列对应一个捕获组。

添加 str.extractall#

添加了 .str.extractall 方法(GH 11386)。与只返回第一个匹配项的 extract 不同。

In [23]: s = pd.Series(["a1a2", "b1", "c1"], ["A", "B", "C"])

In [24]: s
Out[24]: 
A    a1a2
B      b1
C      c1
Length: 3, dtype: object

In [25]: s.str.extract(r"(?P<letter>[ab])(?P<digit>\d)", expand=False)
Out[25]: 
  letter digit
A      a     1
B      b     1
C    NaN   NaN

[3 rows x 2 columns]

extractall 方法返回所有匹配项。

In [26]: s.str.extractall(r"(?P<letter>[ab])(?P<digit>\d)")
Out[26]: 
        letter digit
  match             
A 0          a     1
  1          a     2
B 0          b     1

[3 rows x 2 columns]

str.cat 的变更#

方法 .str.cat() 用于连接 Series 的成员。以前,如果 Series 中存在 NaN 值,对其调用 .str.cat() 会返回 NaN,这与其他 Series.str.* API 不同。此行为已修改,默认忽略 NaN 值。(GH 11435)。

添加了一个新的、更友好的 ValueError,以防止将 sep 作为位置参数而非关键字参数提供的错误。(GH 11334)。

In [27]: pd.Series(['a', 'b', np.nan, 'c']).str.cat(sep=' ')
Out[27]: 'a b c'

In [28]: pd.Series(['a', 'b', np.nan, 'c']).str.cat(sep=' ', na_rep='?')
Out[28]: 'a b ? c'
In [2]: pd.Series(['a', 'b', np.nan, 'c']).str.cat(' ')
ValueError: Did you mean to supply a ``sep`` keyword?

日期时间类型四舍五入#

DatetimeIndexTimestampTimedeltaIndexTimedelta 增加了 .round().floor().ceil() 方法,用于对日期时间类进行四舍五入、向下取整和向上取整。(GH 4314, GH 11963

朴素日期时间

In [29]: dr = pd.date_range('20130101 09:12:56.1234', periods=3)

In [30]: dr
Out[30]: 
DatetimeIndex(['2013-01-01 09:12:56.123400', '2013-01-02 09:12:56.123400',
               '2013-01-03 09:12:56.123400'],
              dtype='datetime64[ns]', freq='D')

In [31]: dr.round('s')
Out[31]: 
DatetimeIndex(['2013-01-01 09:12:56', '2013-01-02 09:12:56',
               '2013-01-03 09:12:56'],
              dtype='datetime64[ns]', freq=None)

# Timestamp scalar
In [32]: dr[0]
Out[32]: Timestamp('2013-01-01 09:12:56.123400')

In [33]: dr[0].round('10s')
Out[33]: Timestamp('2013-01-01 09:13:00')

时区感知型日期时间在本地时间进行四舍五入、向下取整和向上取整

In [34]: dr = dr.tz_localize('US/Eastern')

In [35]: dr
Out[35]: 
DatetimeIndex(['2013-01-01 09:12:56.123400-05:00',
               '2013-01-02 09:12:56.123400-05:00',
               '2013-01-03 09:12:56.123400-05:00'],
              dtype='datetime64[ns, US/Eastern]', freq=None)

In [36]: dr.round('s')
Out[36]: 
DatetimeIndex(['2013-01-01 09:12:56-05:00', '2013-01-02 09:12:56-05:00',
               '2013-01-03 09:12:56-05:00'],
              dtype='datetime64[ns, US/Eastern]', freq=None)

Timedelta

In [37]: t = pd.timedelta_range('1 days 2 hr 13 min 45 us', periods=3, freq='d')

In [38]: t
Out[38]: 
TimedeltaIndex(['1 days 02:13:00.000045', '2 days 02:13:00.000045',
                '3 days 02:13:00.000045'],
               dtype='timedelta64[ns]', freq='D')

In [39]: t.round('10min')
Out[39]: TimedeltaIndex(['1 days 02:10:00', '2 days 02:10:00', '3 days 02:10:00'], dtype='timedelta64[ns]', freq=None)

# Timedelta scalar
In [40]: t[0]
Out[40]: Timedelta('1 days 02:13:00.000045')

In [41]: t[0].round('2h')
Out[41]: Timedelta('1 days 02:00:00')

此外,.round().floor().ceil() 将通过 Series.dt 访问器提供。

In [42]: s = pd.Series(dr)

In [43]: s
Out[43]: 
0   2013-01-01 09:12:56.123400-05:00
1   2013-01-02 09:12:56.123400-05:00
2   2013-01-03 09:12:56.123400-05:00
Length: 3, dtype: datetime64[ns, US/Eastern]

In [44]: s.dt.round('D')
Out[44]: 
0   2013-01-01 00:00:00-05:00
1   2013-01-02 00:00:00-05:00
2   2013-01-03 00:00:00-05:00
Length: 3, dtype: datetime64[ns, US/Eastern]

FloatIndex 中整数的格式化#

FloatIndex 中的整数(例如 1.)现在格式化时带有小数点和一个 0,例如 1.0GH 11713)。此更改不仅影响控制台显示,还影响 .to_csv.to_html 等 IO 方法的输出。

之前行为

In [2]: s = pd.Series([1, 2, 3], index=np.arange(3.))

In [3]: s
Out[3]:
0    1
1    2
2    3
dtype: int64

In [4]: s.index
Out[4]: Float64Index([0.0, 1.0, 2.0], dtype='float64')

In [5]: print(s.to_csv(path=None))
0,1
1,2
2,3

新行为

In [45]: s = pd.Series([1, 2, 3], index=np.arange(3.))

In [46]: s
Out[46]: 
0.0    1
1.0    2
2.0    3
Length: 3, dtype: int64

In [47]: s.index
Out[47]: Index([0.0, 1.0, 2.0], dtype='float64')

In [48]: print(s.to_csv(path_or_buf=None, header=False))
0.0,1
1.0,2
2.0,3

dtype 赋值行为的变更#

当 DataFrame 的切片使用相同 dtype 的新切片进行更新时,DataFrame 的 dtype 现在将保持不变。(GH 10503

之前行为

In [5]: df = pd.DataFrame({'a': [0, 1, 1],
                           'b': pd.Series([100, 200, 300], dtype='uint32')})

In [7]: df.dtypes
Out[7]:
a     int64
b    uint32
dtype: object

In [8]: ix = df['a'] == 1

In [9]: df.loc[ix, 'b'] = df.loc[ix, 'b']

In [11]: df.dtypes
Out[11]:
a    int64
b    int64
dtype: object

新行为

In [49]: df = pd.DataFrame({'a': [0, 1, 1],
   ....:                    'b': pd.Series([100, 200, 300], dtype='uint32')})
   ....: 

In [50]: df.dtypes
Out[50]: 
a     int64
b    uint32
Length: 2, dtype: object

In [51]: ix = df['a'] == 1

In [52]: df.loc[ix, 'b'] = df.loc[ix, 'b']

In [53]: df.dtypes
Out[53]: 
a     int64
b    uint32
Length: 2, dtype: object

当 DataFrame 的整数切片被可以使用新的浮点切片部分更新,且这些浮点数可以在不损失精度的情况下被向下转换为整数时,该切片的 dtype 将被设置为 float 而不是 integer。

之前行为

In [4]: df = pd.DataFrame(np.array(range(1,10)).reshape(3,3),
                          columns=list('abc'),
                          index=[[4,4,8], [8,10,12]])

In [5]: df
Out[5]:
      a  b  c
4 8   1  2  3
  10  4  5  6
8 12  7  8  9

In [7]: df.ix[4, 'c'] = np.array([0., 1.])

In [8]: df
Out[8]:
      a  b  c
4 8   1  2  0
  10  4  5  1
8 12  7  8  9

新行为

In [54]: df = pd.DataFrame(np.array(range(1,10)).reshape(3,3),
   ....:                   columns=list('abc'),
   ....:                   index=[[4,4,8], [8,10,12]])
   ....: 

In [55]: df
Out[55]: 
      a  b  c
4 8   1  2  3
  10  4  5  6
8 12  7  8  9

[3 rows x 3 columns]

In [56]: df.loc[4, 'c'] = np.array([0., 1.])

In [57]: df
Out[57]: 
      a  b  c
4 8   1  2  0
  10  4  5  1
8 12  7  8  9

[3 rows x 3 columns]

to_xarray 方法#

在 pandas 的未来版本中,我们将弃用 Panel 和其他 > 2 维对象。为了提供连续性,所有 NDFrame 对象都增加了 .to_xarray() 方法,以便转换为 xarray 对象,后者提供了类似 pandas 的 > 2 维接口。(GH 11972

请参阅xarray 完整文档

In [1]: p = Panel(np.arange(2*3*4).reshape(2,3,4))

In [2]: p.to_xarray()
Out[2]:
<xarray.DataArray (items: 2, major_axis: 3, minor_axis: 4)>
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
Coordinates:
  * items       (items) int64 0 1
  * major_axis  (major_axis) int64 0 1 2
  * minor_axis  (minor_axis) int64 0 1 2 3

Latex 表示#

DataFrame 增加了 ._repr_latex_() 方法,以便在 ipython/jupyter notebook 中使用 nbconvert 转换为 latex 格式。(GH 11778

请注意,必须通过设置选项 pd.display.latex.repr=True 来激活此功能(GH 12182)。

例如,如果您有一个打算使用 nbconvert 转换为 latex 的 jupyter notebook,请在第一个单元格中放置语句 pd.display.latex.repr=True,以便其中包含的 DataFrame 输出也存储为 latex 格式。

选项 display.latex.escapedisplay.latex.longtable 也已添加到配置中,并由 to_latex 方法自动使用。更多信息请参阅可用选项文档

pd.read_sas() 的变更#

read_sas 增加了读取 SAS7BDAT 文件(包括压缩文件)的能力。文件可以整体读取或增量读取。完整详情请参见此处。(GH 4052

其他增强功能#

  • 处理 SAS xport 文件中的截断浮点数(GH 11713

  • Series.to_string 中添加了隐藏索引的选项(GH 11729

  • read_excel 现在支持格式为 s3://bucketname/filename 的 s3 url(GH 11447

  • 从 s3 读取时,增加了对 AWS_S3_HOST 环境变量的支持(GH 12198

  • 现在实现了 Panel.round() 的一个简单版本(GH 11763

  • 对于 Python 3.x,round(DataFrame)round(Series)round(Panel) 将会工作(GH 11763

  • sys.getsizeof(obj) 返回 pandas 对象的内存使用量,包括其包含的值(GH 11597

  • Series 增加了 is_unique 属性(GH 11946

  • DataFrame.quantileSeries.quantile 现在接受 interpolation 关键字参数(GH 10174)。

  • 添加了 DataFrame.style.format,用于更灵活地格式化单元格值(GH 11692

  • DataFrame.select_dtypes 现在允许使用 np.float16 类型代码(GH 11990

  • pivot_table() 现在接受大多数可迭代对象作为 values 参数(GH 12017

  • 添加了 Google BigQuery 服务账号认证支持,这使得在远程服务器上进行认证成为可能。(GH 11881, GH 12572)。更多详情请参阅此处

  • HDFStore 现在是可迭代的:for k in store 等同于 for k in store.keys()GH 12221)。

  • Period.dt 添加了缺失的方法/字段(GH 8848

  • 整个代码库已符合 PEP 规范(GH 12096

向后不兼容的 API 变更#

  • .to_string(index=False) 方法的输出中已移除开头的空白字符(GH 11833

  • Series.round() 方法中已移除 out 参数。(GH 11763

  • DataFrame.round() 在返回值中保持非数字列不变,而不是引发异常。(GH 11885

  • DataFrame.head(0)DataFrame.tail(0) 返回空 DataFrame,而不是 self。(GH 11937

  • Series.head(0)Series.tail(0) 返回空 Series,而不是 self。(GH 11937

  • to_msgpackread_msgpack 的编码现在默认为 'utf-8'。(GH 12170

  • 文本文件解析函数(.read_csv().read_table().read_fwf())的关键字参数顺序已更改,以便将相关参数分组。(GH 11555

  • NaTType.isoformat 现在返回字符串 'NaT',以便可以将结果传递给 Timestamp 的构造函数。(GH 12300

NaT 和 Timedelta 操作#

NaTTimedelta 扩展了算术操作,这些操作在适用的情况下也扩展到了 Series 算术。为 datetime64[ns]timedelta64[ns] 定义的操作现在也为 NaT 定义了(GH 11564)。

NaT 现在支持与整数和浮点数进行算术运算。

In [58]: pd.NaT * 1
Out[58]: NaT

In [59]: pd.NaT * 1.5
Out[59]: NaT

In [60]: pd.NaT / 2
Out[60]: NaT

In [61]: pd.NaT * np.nan
Out[61]: NaT

NaT 定义了更多与 datetime64[ns]timedelta64[ns] 的算术操作。

In [62]: pd.NaT / pd.NaT
Out[62]: nan

In [63]: pd.Timedelta('1s') / pd.NaT
Out[63]: nan

NaT 可以表示 datetime64[ns] 空值或 timedelta64[ns] 空值。考虑到这种模糊性,它被视为 timedelta64[ns],这使得更多操作能够成功。

In [64]: pd.NaT + pd.NaT
Out[64]: NaT

# same as
In [65]: pd.Timedelta('1s') + pd.Timedelta('1s')
Out[65]: Timedelta('0 days 00:00:02')

对比

In [3]: pd.Timestamp('19900315') + pd.Timestamp('19900315')
TypeError: unsupported operand type(s) for +: 'Timestamp' and 'Timestamp'

然而,当包装在 Series 中,且其 dtypedatetime64[ns]timedelta64[ns] 时,将遵守 dtype 信息。

In [1]: pd.Series([pd.NaT], dtype='<M8[ns]') + pd.Series([pd.NaT], dtype='<M8[ns]')
TypeError: can only operate on a datetimes for subtraction,
           but the operator [__add__] was passed
In [66]: pd.Series([pd.NaT], dtype='<m8[ns]') + pd.Series([pd.NaT], dtype='<m8[ns]')
Out[66]: 
0   NaT
Length: 1, dtype: timedelta64[ns]

Timedelta 现在支持除以 floats

In [67]: pd.Timedelta('1s') / 2.0
Out[67]: Timedelta('0 days 00:00:00.500000')

Series 中,用 Timestamp 减去 Timedelta 可以正常工作(GH 11925

In [68]: ser = pd.Series(pd.timedelta_range('1 day', periods=3))

In [69]: ser
Out[69]: 
0   1 days
1   2 days
2   3 days
Length: 3, dtype: timedelta64[ns]

In [70]: pd.Timestamp('2012-01-01') - ser
Out[70]: 
0   2011-12-31
1   2011-12-30
2   2011-12-29
Length: 3, dtype: datetime64[ns]

NaT.isoformat() 现在返回 'NaT'。此更改允许 pd.Timestamp 从其 isoformat 重建任何类时间戳对象(GH 12300)。

msgpack 的变更#

在 0.17.0 和 0.18.0 版本中,对 msgpack 写入格式进行了向前不兼容的更改;旧版本的 pandas 无法读取由新版本打包的文件(GH 12129, GH 10527)。

在 0.17.0 中引入并在 0.18.0 中修复的 to_msgpackread_msgpack 中的 bug,导致在 Python 2 中打包的文件无法被 Python 3 读取(GH 12142)。下表描述了 msgpack 的向后和向前兼容性。

警告

打包版本

可解包版本

0.17 之前 / Python 2

任意

0.17 之前 / Python 3

任意

0.17 / Python 2

  • ==0.17 / Python 2

  • >=0.18 / 任意 Python 版本

0.17 / Python 3

>=0.18 / 任意 Python 版本

0.18

>= 0.18

0.18.0 版本向后兼容读取旧版本打包的文件,但在 Python 2 中使用 0.17 版本打包的文件除外,这种情况下只能在 Python 2 中解包。

Signature change for .rank#

Series.rankDataFrame.rank 现在拥有相同的签名(GH 11759

旧签名

In [3]: pd.Series([0,1]).rank(method='average', na_option='keep',
                              ascending=True, pct=False)
Out[3]:
0    1
1    2
dtype: float64

In [4]: pd.DataFrame([0,1]).rank(axis=0, numeric_only=None,
                                 method='average', na_option='keep',
                                 ascending=True, pct=False)
Out[4]:
   0
0  1
1  2

新签名

In [71]: pd.Series([0,1]).rank(axis=0, method='average', numeric_only=False,
   ....:                       na_option='keep', ascending=True, pct=False)
   ....: 
Out[71]: 
0    1.0
1    2.0
Length: 2, dtype: float64

In [72]: pd.DataFrame([0,1]).rank(axis=0, method='average', numeric_only=False,
   ....:                          na_option='keep', ascending=True, pct=False)
   ....: 
Out[72]: 
     0
0  1.0
1  2.0

[2 rows x 1 columns]

QuarterBegin 中 n=0 的错误#

在之前的版本中,QuarterBegin offset 的行为在 n 参数为 0 时,根据日期不同而表现不一致。(GH 11406

固定偏移(anchored offsets)对于 n=0 的一般语义是:如果日期是锚点(例如,一个季度的开始日期),则不移动日期;否则向前滚动到下一个锚点。

In [73]: d = pd.Timestamp('2014-02-01')

In [74]: d
Out[74]: Timestamp('2014-02-01 00:00:00')

In [75]: d + pd.offsets.QuarterBegin(n=0, startingMonth=2)
Out[75]: Timestamp('2014-02-01 00:00:00')

In [76]: d + pd.offsets.QuarterBegin(n=0, startingMonth=1)
Out[76]: Timestamp('2014-04-01 00:00:00')

对于之前版本的 QuarterBegin offset,如果日期与季度开始日期在同一月份,则日期会被*向后*滚动。

In [3]: d = pd.Timestamp('2014-02-15')

In [4]: d + pd.offsets.QuarterBegin(n=0, startingMonth=2)
Out[4]: Timestamp('2014-02-01 00:00:00')

此行为已在版本 0.18.0 中得到纠正,与 MonthBeginYearBegin 等其他固定偏移保持一致。

In [77]: d = pd.Timestamp('2014-02-15')

In [78]: d + pd.offsets.QuarterBegin(n=0, startingMonth=2)
Out[78]: Timestamp('2014-05-01 00:00:00')

Resample API#

上面 窗口函数 API 中的更改类似,.resample(...) 正在更改为更像 groupby 的 API。(GH 11732, GH 12702, GH 12202, GH 12332, GH 12334, GH 12348, GH 12448)。

In [79]: np.random.seed(1234)

In [80]: df = pd.DataFrame(np.random.rand(10,4),
   ....:                   columns=list('ABCD'),
   ....:                   index=pd.date_range('2010-01-01 09:00:00',
   ....:                                       periods=10, freq='s'))
   ....: 

In [81]: df
Out[81]: 
                            A         B         C         D
2010-01-01 09:00:00  0.191519  0.622109  0.437728  0.785359
2010-01-01 09:00:01  0.779976  0.272593  0.276464  0.801872
2010-01-01 09:00:02  0.958139  0.875933  0.357817  0.500995
2010-01-01 09:00:03  0.683463  0.712702  0.370251  0.561196
2010-01-01 09:00:04  0.503083  0.013768  0.772827  0.882641
2010-01-01 09:00:05  0.364886  0.615396  0.075381  0.368824
2010-01-01 09:00:06  0.933140  0.651378  0.397203  0.788730
2010-01-01 09:00:07  0.316836  0.568099  0.869127  0.436173
2010-01-01 09:00:08  0.802148  0.143767  0.704261  0.704581
2010-01-01 09:00:09  0.218792  0.924868  0.442141  0.909316

[10 rows x 4 columns]

旧 API:

您会编写一个立即求值的重采样操作。如果未提供 how 参数,则默认为 how='mean'

In [6]: df.resample('2s')
Out[6]:
                         A         B         C         D
2010-01-01 09:00:00  0.485748  0.447351  0.357096  0.793615
2010-01-01 09:00:02  0.820801  0.794317  0.364034  0.531096
2010-01-01 09:00:04  0.433985  0.314582  0.424104  0.625733
2010-01-01 09:00:06  0.624988  0.609738  0.633165  0.612452
2010-01-01 09:00:08  0.510470  0.534317  0.573201  0.806949

您也可以直接指定 how

In [7]: df.resample('2s', how='sum')
Out[7]:
                         A         B         C         D
2010-01-01 09:00:00  0.971495  0.894701  0.714192  1.587231
2010-01-01 09:00:02  1.641602  1.588635  0.728068  1.062191
2010-01-01 09:00:04  0.867969  0.629165  0.848208  1.251465
2010-01-01 09:00:06  1.249976  1.219477  1.266330  1.224904
2010-01-01 09:00:08  1.020940  1.068634  1.146402  1.613897

新 API:

现在,您可以将 .resample(..) 写成类似 .groupby(...) 的两阶段操作,它会产生一个 Resampler 对象。

In [82]: r = df.resample('2s')

In [83]: r
Out[83]: <pandas.core.resample.DatetimeIndexResampler object at 0x7fe88cbf8f10>

向下采样(Downsampling)#

然后您可以使用此对象执行操作。这些是向下采样操作(从高频率到低频率)。

In [84]: r.mean()
Out[84]: 
                            A         B         C         D
2010-01-01 09:00:00  0.485748  0.447351  0.357096  0.793615
2010-01-01 09:00:02  0.820801  0.794317  0.364034  0.531096
2010-01-01 09:00:04  0.433985  0.314582  0.424104  0.625733
2010-01-01 09:00:06  0.624988  0.609738  0.633165  0.612452
2010-01-01 09:00:08  0.510470  0.534317  0.573201  0.806949

[5 rows x 4 columns]
In [85]: r.sum()
Out[85]: 
                            A         B         C         D
2010-01-01 09:00:00  0.971495  0.894701  0.714192  1.587231
2010-01-01 09:00:02  1.641602  1.588635  0.728068  1.062191
2010-01-01 09:00:04  0.867969  0.629165  0.848208  1.251465
2010-01-01 09:00:06  1.249976  1.219477  1.266330  1.224904
2010-01-01 09:00:08  1.020940  1.068634  1.146402  1.613897

[5 rows x 4 columns]

此外,resample 现在支持 getitem 操作,以便对特定列执行重采样。

In [86]: r[['A','C']].mean()
Out[86]: 
                            A         C
2010-01-01 09:00:00  0.485748  0.357096
2010-01-01 09:00:02  0.820801  0.364034
2010-01-01 09:00:04  0.433985  0.424104
2010-01-01 09:00:06  0.624988  0.633165
2010-01-01 09:00:08  0.510470  0.573201

[5 rows x 2 columns]

.aggregate 类型操作。

In [87]: r.agg({'A' : 'mean', 'B' : 'sum'})
Out[87]: 
                            A         B
2010-01-01 09:00:00  0.485748  0.894701
2010-01-01 09:00:02  0.820801  1.588635
2010-01-01 09:00:04  0.433985  0.629165
2010-01-01 09:00:06  0.624988  1.219477
2010-01-01 09:00:08  0.510470  1.068634

[5 rows x 2 columns]

这些访问器当然可以组合使用

In [88]: r[['A','B']].agg(['mean','sum'])
Out[88]: 
                            A                   B          
                         mean       sum      mean       sum
2010-01-01 09:00:00  0.485748  0.971495  0.447351  0.894701
2010-01-01 09:00:02  0.820801  1.641602  0.794317  1.588635
2010-01-01 09:00:04  0.433985  0.867969  0.314582  0.629165
2010-01-01 09:00:06  0.624988  1.249976  0.609738  1.219477
2010-01-01 09:00:08  0.510470  1.020940  0.534317  1.068634

[5 rows x 4 columns]

向上采样(Upsampling)#

向上采样操作将您从低频率带到高频率。这些操作现在通过 Resampler 对象使用 backfill(), ffill(), fillna()asfreq() 方法执行。

In [89]: s = pd.Series(np.arange(5, dtype='int64'),
              index=pd.date_range('2010-01-01', periods=5, freq='Q'))

In [90]: s
Out[90]:
2010-03-31    0
2010-06-30    1
2010-09-30    2
2010-12-31    3
2011-03-31    4
Freq: Q-DEC, Length: 5, dtype: int64

之前

In [6]: s.resample('M', fill_method='ffill')
Out[6]:
2010-03-31    0
2010-04-30    0
2010-05-31    0
2010-06-30    1
2010-07-31    1
2010-08-31    1
2010-09-30    2
2010-10-31    2
2010-11-30    2
2010-12-31    3
2011-01-31    3
2011-02-28    3
2011-03-31    4
Freq: M, dtype: int64

新 API

In [91]: s.resample('M').ffill()
Out[91]:
2010-03-31    0
2010-04-30    0
2010-05-31    0
2010-06-30    1
2010-07-31    1
2010-08-31    1
2010-09-30    2
2010-10-31    2
2010-11-30    2
2010-12-31    3
2011-01-31    3
2011-02-28    3
2011-03-31    4
Freq: M, Length: 13, dtype: int64

注意

在新 API 中,您可以进行向下采样或向上采样。先前的实现允许您传递聚合函数(例如 mean),即使您正在进行向上采样,这会带来一些困惑。

旧 API 将继续工作,但带有弃用警告#

警告

这个新的 resample API 包括对 0.18.0 之前 API 的一些内部更改,以便在大多数情况下带有弃用警告,因为重采样操作返回一个延迟对象。我们可以拦截操作并执行(0.18.0 之前的)API 所做的事情(并带有警告)。这里有一个典型的用例

In [4]: r = df.resample('2s')

In [6]: r*10
pandas/tseries/resample.py:80: FutureWarning: .resample() is now a deferred operation
use .resample(...).mean() instead of .resample(...)

Out[6]:
                      A         B         C         D
2010-01-01 09:00:00  4.857476  4.473507  3.570960  7.936154
2010-01-01 09:00:02  8.208011  7.943173  3.640340  5.310957
2010-01-01 09:00:04  4.339846  3.145823  4.241039  6.257326
2010-01-01 09:00:06  6.249881  6.097384  6.331650  6.124518
2010-01-01 09:00:08  5.104699  5.343172  5.732009  8.069486

但是,直接在 Resampler 上进行获取和赋值操作将引发 ValueError

In [7]: r.iloc[0] = 5
ValueError: .resample() is now a deferred operation
use .resample(...).mean() instead of .resample(...)

存在一种情况,新 API 在使用原始代码时无法执行所有操作。这段代码旨在每 2 秒重采样一次,取 mean,然后取这些结果的 min

In [4]: df.resample('2s').min()
Out[4]:
A    0.433985
B    0.314582
C    0.357096
D    0.531096
dtype: float64

新 API 将会

In [89]: df.resample('2s').min()
Out[89]: 
                            A         B         C         D
2010-01-01 09:00:00  0.191519  0.272593  0.276464  0.785359
2010-01-01 09:00:02  0.683463  0.712702  0.357817  0.500995
2010-01-01 09:00:04  0.364886  0.013768  0.075381  0.368824
2010-01-01 09:00:06  0.316836  0.568099  0.397203  0.436173
2010-01-01 09:00:08  0.218792  0.143767  0.442141  0.704581

[5 rows x 4 columns]

好消息是,新 API 和旧 API 的返回维度将不同,因此这应该会明确地引发异常。

要复制原始操作

In [90]: df.resample('2s').mean().min()
Out[90]: 
A    0.433985
B    0.314582
C    0.357096
D    0.531096
Length: 4, dtype: float64

eval 的更改#

在之前的版本中,eval 表达式中的新列赋值会导致对 DataFrame 进行原地更改。(GH 9297, GH 8664, GH 10486

In [91]: df = pd.DataFrame({'a': np.linspace(0, 10, 5), 'b': range(5)})

In [92]: df
Out[92]: 
      a  b
0   0.0  0
1   2.5  1
2   5.0  2
3   7.5  3
4  10.0  4

[5 rows x 2 columns]
In [12]: df.eval('c = a + b')
FutureWarning: eval expressions containing an assignment currentlydefault to operating inplace.
This will change in a future version of pandas, use inplace=True to avoid this warning.

In [13]: df
Out[13]:
      a  b     c
0   0.0  0   0.0
1   2.5  1   3.5
2   5.0  2   7.0
3   7.5  3  10.5
4  10.0  4  14.0

在版本 0.18.0 中,添加了一个新的 inplace 关键字,用于选择赋值是原地进行还是返回副本。

In [93]: df
Out[93]: 
      a  b     c
0   0.0  0   0.0
1   2.5  1   3.5
2   5.0  2   7.0
3   7.5  3  10.5
4  10.0  4  14.0

[5 rows x 3 columns]

In [94]: df.eval('d = c - b', inplace=False)
Out[94]: 
      a  b     c     d
0   0.0  0   0.0   0.0
1   2.5  1   3.5   2.5
2   5.0  2   7.0   5.0
3   7.5  3  10.5   7.5
4  10.0  4  14.0  10.0

[5 rows x 4 columns]

In [95]: df
Out[95]: 
      a  b     c
0   0.0  0   0.0
1   2.5  1   3.5
2   5.0  2   7.0
3   7.5  3  10.5
4  10.0  4  14.0

[5 rows x 3 columns]

In [96]: df.eval('d = c - b', inplace=True)

In [97]: df
Out[97]: 
      a  b     c     d
0   0.0  0   0.0   0.0
1   2.5  1   3.5   2.5
2   5.0  2   7.0   5.0
3   7.5  3  10.5   7.5
4  10.0  4  14.0  10.0

[5 rows x 4 columns]

警告

为了向后兼容,如果未指定 inplace,则默认为 True。这将在未来版本的 pandas 中改变。如果您的代码依赖于原地赋值,您应该更新代码以显式设置 inplace=True

inplace 关键字参数也已添加到 query 方法中。

In [98]: df.query('a > 5')
Out[98]: 
      a  b     c     d
3   7.5  3  10.5   7.5
4  10.0  4  14.0  10.0

[2 rows x 4 columns]

In [99]: df.query('a > 5', inplace=True)

In [100]: df
Out[100]: 
      a  b     c     d
3   7.5  3  10.5   7.5
4  10.0  4  14.0  10.0

[2 rows x 4 columns]

警告

请注意,queryinplace 的默认值为 False,这与之前的版本一致。

eval 也已更新,允许使用多行表达式进行多个赋值。这些表达式将按顺序逐一求值。只有赋值在多行表达式中是有效的。

In [101]: df
Out[101]: 
      a  b     c     d
3   7.5  3  10.5   7.5
4  10.0  4  14.0  10.0

[2 rows x 4 columns]

In [102]: df.eval("""
   .....: e = d + a
   .....: f = e - 22
   .....: g = f / 2.0""", inplace=True)
   .....: 

In [103]: df
Out[103]: 
      a  b     c     d     e    f    g
3   7.5  3  10.5   7.5  15.0 -7.0 -3.5
4  10.0  4  14.0  10.0  20.0 -2.0 -1.0

[2 rows x 7 columns]

其他 API 更改#

  • DataFrame.between_timeSeries.between_time 现在只解析固定集合的时间字符串。不再支持解析日期字符串,并将引发 ValueError。(GH 11818

    In [107]: s = pd.Series(range(10), pd.date_range('2015-01-01', freq='H', periods=10))
    
    In [108]: s.between_time("7:00am", "9:00am")
    Out[108]:
    2015-01-01 07:00:00    7
    2015-01-01 08:00:00    8
    2015-01-01 09:00:00    9
    Freq: H, Length: 3, dtype: int64
    

    这现在会引发错误。

    In [2]: s.between_time('20150101 07:00:00','20150101 09:00:00')
    ValueError: Cannot convert arg ['20150101 07:00:00'] to a time.
    
  • .memory_usage() 现在包含索引中的值,.info() 中的 memory_usage 也一样。(GH 11597

  • DataFrame.to_latex() 现在在 Python 2 中使用参数 encoding 支持非 ASCII 编码(例如 utf-8)。(GH 7061

  • pandas.merge()DataFrame.merge() 在尝试与非 DataFrame 类型或其子类的对象合并时,将显示特定的错误消息。(GH 12081

  • DataFrame.unstackSeries.unstack 现在接受 fill_value 关键字,以便在 unstack 导致结果 DataFrame 出现缺失值时直接替换这些值。此外,指定 fill_value 将保留原始 stacked 数据的类型。(GH 9746

  • 作为 窗口函数重采样 新 API 的一部分,聚合函数已得到澄清,在无效聚合时会引发更具信息量的错误消息。(GH 9052)。完整的示例集在 groupby 中给出。

  • NDFrame 对象的统计函数(如 sum(), mean(), min())现在在为 **kwargs 传递非 numpy 兼容参数时将引发错误。(GH 12301

  • .to_latex.to_html 获得了与 .to_csv 类似的 decimal 参数;默认值为 '.'。(GH 12031

  • 使用空数据但带有索引构建 DataFrame 时,错误消息更具帮助性。(GH 8020

  • .describe() 现在将正确处理布尔 dtype 作为分类变量。(GH 6625

  • 使用用户定义输入进行无效 .transform 时,错误消息更具帮助性。(GH 10165

  • 指数加权函数现在允许直接指定 alpha(GH 10789),并在参数违反 0 < alpha <= 1 时引发 ValueError。(GH 12492

弃用#

  • 函数 pd.rolling_*, pd.expanding_*pd.ewm* 已被弃用,并由相应的method调用替换。请注意,新的建议语法包含所有参数(即使是默认参数)。(GH 11603

    In [1]: s = pd.Series(range(3))
    
    In [2]: pd.rolling_mean(s,window=2,min_periods=1)
            FutureWarning: pd.rolling_mean is deprecated for Series and
                 will be removed in a future version, replace with
                 Series.rolling(min_periods=1,window=2,center=False).mean()
    Out[2]:
            0    0.0
            1    0.5
            2    1.5
            dtype: float64
    
    In [3]: pd.rolling_cov(s, s, window=2)
            FutureWarning: pd.rolling_cov is deprecated for Series and
                 will be removed in a future version, replace with
                 Series.rolling(window=2).cov(other=<Series>)
    Out[3]:
            0    NaN
            1    0.5
            2    0.5
            dtype: float64
    
  • .rolling, .expanding.ewm(新)函数中的 freqhow 参数已弃用,并将在未来版本中移除。您可以在创建窗口函数之前简单地对输入进行重采样。(GH 11603)。

    例如,为了获取滚动 5 天窗口的最大值,可以用 s.resample('D').mean().rolling(window=5).max() 来代替 s.rolling(window=5,freq='D').max(),它首先将数据重采样为每日数据,然后提供一个滚动的 5 天窗口。

  • 函数 pd.tseries.frequencies.get_offset_name 已被弃用。请使用 offset 的 .freqstr 属性作为替代。(GH 11192

  • pandas.stats.fama_macbeth 例程已弃用,并将在未来版本中移除。(GH 6077

  • pandas.stats.ols, pandas.stats.plmpandas.stats.var 例程已弃用,并将在未来版本中移除。(GH 6077

  • 在使用 HDFStore.select 中长期弃用的语法时,其中 where 子句不是字符串类型,会显示 FutureWarning 而非 DeprecationWarning。(GH 12027

  • pandas.options.display.mpl_style 配置已被弃用,并将在未来版本的 pandas 中移除。matplotlib 的 style sheets 可以更好地处理此功能。(GH 11783)。

移除弃用的浮点索引器#

GH 4892 中,在非 Float64Index 上使用浮点数进行索引已被弃用(在版本 0.14.0 中)。在 0.18.0 中,此弃用警告已移除,现在将引发 TypeError。(GH 12165, GH 12333

In [104]: s = pd.Series([1, 2, 3], index=[4, 5, 6])

In [105]: s
Out[105]: 
4    1
5    2
6    3
Length: 3, dtype: int64

In [106]: s2 = pd.Series([1, 2, 3], index=list('abc'))

In [107]: s2
Out[107]: 
a    1
b    2
c    3
Length: 3, dtype: int64

之前行为

# this is label indexing
In [2]: s[5.0]
FutureWarning: scalar indexers for index type Int64Index should be integers and not floating point
Out[2]: 2

# this is positional indexing
In [3]: s.iloc[1.0]
FutureWarning: scalar indexers for index type Int64Index should be integers and not floating point
Out[3]: 2

# this is label indexing
In [4]: s.loc[5.0]
FutureWarning: scalar indexers for index type Int64Index should be integers and not floating point
Out[4]: 2

# .ix would coerce 1.0 to the positional 1, and index
In [5]: s2.ix[1.0] = 10
FutureWarning: scalar indexers for index type Index should be integers and not floating point

In [6]: s2
Out[6]:
a     1
b    10
c     3
dtype: int64

新行为

对于 iloc,通过浮点标量进行获取和设置将始终引发错误。

In [3]: s.iloc[2.0]
TypeError: cannot do label indexing on <class 'pandas.indexes.numeric.Int64Index'> with these indexers [2.0] of <type 'float'>

其他索引器在获取和设置时都会强制转换为类似整数的类型。FutureWarning 已为 .loc, .ix[] 删除。

In [108]: s[5.0]
Out[108]: 2

In [109]: s.loc[5.0]
Out[109]: 2

和设置

In [110]: s_copy = s.copy()

In [111]: s_copy[5.0] = 10

In [112]: s_copy
Out[112]: 
4     1
5    10
6     3
Length: 3, dtype: int64

In [113]: s_copy = s.copy()

In [114]: s_copy.loc[5.0] = 10

In [115]: s_copy
Out[115]: 
4     1
5    10
6     3
Length: 3, dtype: int64

使用 .ix 和浮点索引器进行位置设置将把此值 ADD 到索引中,而不是像以前那样按位置设置值。

In [3]: s2.ix[1.0] = 10
In [4]: s2
Out[4]:
a       1
b       2
c       3
1.0    10
dtype: int64

对于非 Float64Index,切片操作也会将类似整数的浮点数强制转换为整数。

In [116]: s.loc[5.0:6]
Out[116]: 
5    2
6    3
Length: 2, dtype: int64

请注意,对于无法强制转换为整数的浮点数,将排除基于标签的边界

In [117]: s.loc[5.1:6]
Out[117]: 
6    3
Length: 1, dtype: int64

Float64Index 上的浮点索引未改变。

In [118]: s = pd.Series([1, 2, 3], index=np.arange(3.))

In [119]: s[1.0]
Out[119]: 2

In [120]: s[1.0:2.5]
Out[120]: 
1.0    2
2.0    3
Length: 2, dtype: int64

移除之前版本弃用/更改的项目#

  • 移除 rolling_corr_pairwise,转而使用 .rolling().corr(pairwise=True)GH 4950

  • 移除 expanding_corr_pairwise,转而使用 .expanding().corr(pairwise=True)GH 4950

  • 移除 DataMatrix 模块。无论如何,此模块并未导入到 pandas 命名空间中。(GH 12111

  • 移除 DataFrame.duplicated()DataFrame.drop_duplicates() 中的 cols 关键字,转而使用 subset。(GH 6680

  • 移除 pd.io.sql 命名空间中的 read_frameframe_query 函数(两者均为 pd.read_sql 的别名)以及 write_frame 函数(to_sql 的别名),这些函数自 0.14.0 版本起已被弃用。(GH 6292)。

  • 移除 .factorize() 中的 order 关键字。(GH 6930

性能改进#

  • 改进了 andrews_curves 的性能。(GH 11534

  • 改进了大型 DatetimeIndex, PeriodIndexTimedeltaIndex 的操作性能,包括 NaT。(GH 10277

  • 改进了 pandas.concat 的性能。(GH 11958

  • 改进了 StataReader 的性能。(GH 11591

  • 改进了使用包含 NaT 的 datetime Series 构建 Categoricals 的性能。(GH 12077

  • 改进了 ISO 8601 日期解析的性能,包括无分隔符的日期(GH 11899)、带前导零的日期(GH 11871)以及时区前带空格的日期(GH 9714)。

错误修复#

  • DataFrame 为空时 `GroupBy.size` 的错误。(GH 11699

  • 请求时间段的倍数时 `Period.end_time` 的错误。(GH 11738

  • 使用带时区的 datetime 时 `.clip` 的回归错误。(GH 11838

  • 边界恰好落在频率上时 `date_range` 的错误。(GH 11804, GH 12409

  • 将嵌套字典传递给 `.groupby(...).agg(...)` 的一致性错误。(GH 9052

  • 在 `Timedelta` 构造函数中接受 unicode。(GH 11995

  • 增量读取时 `StataReader` 的值标签读取错误。(GH 12014

  • 当 `n` 参数为 `0` 时,矢量化 `DateOffset` 的错误。(GH 11370

  • 与 numpy 1.11 关于 `NaT` 比较更改的兼容性问题。(GH 12049

  • 在线程中从 `StringIO` 读取时 `read_csv` 的错误。(GH 11790

  • 在 factorizing 和使用 `Categoricals` 时,未将 datetimelikes 中的 `NaT` 视为缺失值的错误。(GH 12077

  • Series 的值是带时区的对象时 getitem 的错误。(GH 12089

  • 当其中一个变量为 'name' 时 `Series.str.get_dummies` 的错误。(GH 12180

  • 连接带时区的 NaT series 时 `pd.concat` 的错误。(GH 11693, GH 11755, GH 12217

  • 读取版本 <= 108 的文件时 `pd.read_stata` 的错误。(GH 12232

  • 当索引为 `DatetimeIndex` 且包含非零纳秒部分时,使用 `Nano` 频率对 `Series.resample` 进行重采样的错误。(GH 12037

  • 使用 `.nunique` 和稀疏索引进行重采样时的错误。(GH 12352

  • 移除了一些编译器警告。(GH 12471

  • 解决 python 3.5 中与 `boto` 的兼容性问题。(GH 11915

  • 从带时区的 `Timestamp` 或 `DatetimeIndex` 中减去 `NaT` 的错误。(GH 11718

  • 减去单个带时区的 `Timestamp` Series 的错误。(GH 12290

  • 在 PY2 中使用兼容迭代器支持 `.next()`。(GH 12299

  • 带有负值时 `Timedelta.round` 的错误。(GH 11690

  • 针对 `CategoricalIndex` 使用 `.loc` 可能导致普通 `Index` 的错误。(GH 11586

  • 当存在重复列名时 `DataFrame.info` 的错误。(GH 11761

  • 带时区的 datetime 对象进行 `.copy` 的错误。(GH 11794

  • `Series.apply` 和 `Series.map` 中未对 `timedelta64` 进行装箱的错误。(GH 11349

  • 使用带时区的 `Series` 时 `DataFrame.set_index()` 的错误。(GH 12358

  • `DataFrame` 子类中 `AttributeError` 未传播的错误。(GH 11808

  • 对带时区数据进行 groupby 时,选择未返回 `Timestamp` 的错误。(GH 11616

  • `pd.read_clipboard` 和 `pd.to_clipboard` 函数不支持 Unicode 的错误;升级包含 `pyperclip` 到 v1.5.15。(GH 9263

  • 包含赋值的 `DataFrame.query` 的错误。(GH 8664

  • 如果 DataFrame 包含 object 列,`from_msgpack` 中 `__contains__()` 对解包的 DataFrame 列失败的错误。(GH 11880

  • 对带有 `TimedeltaIndex` 的分类数据进行 `.resample` 的错误。(GH 12169

  • 错误:将标量 datetime 广播到 DataFrame 时,时区信息会丢失 (GH 11682)

  • 错误:从具有混合时区的 Timestamp 创建 Index 时会强制转换为 UTC (GH 11488)

  • 错误:to_numeric 在输入维度大于一维时不会引发异常 (GH 11776)

  • 错误:解析非零分钟的时区偏移字符串时存在问题 (GH 11708)

  • 错误:在 matplotlib 1.5+ 版本下,df.plot 使用不正确的颜色绘制条形图 (GH 11614)

  • 错误:groupbyplot 方法在使用关键字参数时存在问题 (GH 11805)。

  • 错误:DataFrame.duplicateddrop_duplicates 在设置 keep=False 时会导致产生错误的匹配项 (GH 11864)

  • 错误:使用重复键的 .loc 结果可能导致 Index 的 dtype 不正确 (GH 11497)

  • 错误:pd.rolling_median 在内存充足的情况下仍可能出现内存分配失败 (GH 11696)

  • 错误:DataFrame.style 中出现多余的零 (GH 12134)

  • 错误:DataFrame.style 中整数列的索引没有从 0 开始 (GH 12125)

  • 错误:.style.bar 在特定浏览器中可能无法正常渲染 (GH 11678)

  • 错误:TimedeltaTimedeltanumpy.array 进行富比较(rich comparison)时导致无限递归 (GH 11835)

  • 错误:DataFrame.round 丢弃列索引名称 (GH 11986)

  • 错误:在混合 dtype 的 Dataframe 中替换值时,df.replace 存在问题 (GH 11698)

  • 错误:Index 在未提供新名称时无法复制传入的 Index 的名称 (GH 11193)

  • 错误:当存在空工作表且 sheetname=None 时,read_excel 无法读取任何非空工作表 (GH 11711)

  • 错误:当提供了关键字参数 parse_datesdate_parser 时,read_excel 未能引发 NotImplemented 错误 (GH 11544)

  • 错误:使用 pymysql 连接时,read_sql 未能返回分块数据 (GH 11522)

  • 错误:.to_csv 忽略了浮点型索引的格式化参数 decimal, na_rep, float_format (GH 11553)

  • 错误:Int64IndexFloat64Index 阻止了模运算符的使用 (GH 9244)

  • 错误:针对非词典排序(non-lexsorted)的 MultiIndexes 调用 MultiIndex.drop 存在问题 (GH 12078)

  • 错误:对空的 DataFrame 进行掩码操作时,DataFrame 存在问题 (GH 11859)

  • 错误:当列数与提供的系列数不匹配时,.plot 可能修改 colors 输入 (GH 12039)。

  • 错误:当索引具有 CustomBusinessDay 频率时,Series.plot 会失败 (GH 7222)。

  • 错误:使用 sqlite 回退时,.to_sql 处理 datetime.time 值存在问题 (GH 8341)

  • 错误:当 squeeze=True 时,read_excel 无法读取只有一列的数据 (GH 12157)

  • 错误:read_excel 无法读取一个空列 (GH 12292, GH 9002)

  • 错误:当 dataframe 只有一行时,.groupby 对错误的列未引发 KeyError (GH 11741)

  • 错误:.read_csv 在空数据上指定 dtype 时产生错误 (GH 12048)

  • 错误:.read_csv 将形如 '2E' 的字符串错误地识别为有效浮点数 (GH 12237)

  • 错误:使用调试符号构建 pandas 时存在问题 (GH 12123)

  • 已移除 DatetimeIndexmillisecond 属性。该属性总是会引发 ValueError (GH 12019)。

  • 错误:使用只读数据构建 Series 时存在问题 (GH 11502)

  • 已移除 pandas._testing.choice()。应改用 np.random.choice() (GH 12386)。

  • 错误:.loc setitem 索引器阻止了对时区感知型 DatetimeIndex 的使用 (GH 12050)

  • 错误:.style 中的索引和 MultiIndexes 没有显示出来 (GH 11655)

  • 错误:to_msgpackfrom_msgpack 未能正确序列化或反序列化 NaT (GH 12307)。

  • 错误:由于高度相似值导致的舍入误差,.skew.kurt 存在问题 (GH 11974)

  • 错误:Timestamp 构造函数在 HHMMSS 没有用 ':' 分隔时丢失微秒精度 (GH 10041)

  • 错误:如果读取失败,buffer_rd_bytes src->buffer 可能被释放多次,导致段错误 (segfault) (GH 12098)

  • 错误:具有不重叠索引的参数在 crosstab 中会返回 KeyError (GH 10291)

  • 错误:DataFrame.apply 在 dtype 不是 numpy dtype 的情况下没有阻止降维 (reduction) (GH 12244)

  • 错误:使用标量值初始化分类 Series 时存在问题 (GH 12336)

  • 错误:在 .to_datetime 中设置 utc=True 来指定 UTC DatetimeIndex 时存在问题 (GH 11934)

  • 错误:在 read_csv 中增加 CSV 阅读器的缓冲区大小时存在问题 (GH 12494)

  • 错误:为具有重复列名的 DataFrame 设置列时存在问题 (GH 12344)

贡献者#

共有 101 位贡献者为本次发布贡献了补丁。姓名旁带有“+”的贡献者是首次贡献补丁。

  • ARF +

  • Alex Alekseyev +

  • Andrew McPherson +

  • Andrew Rosenfeld

  • Andy Hayden

  • Anthonios Partheniou

  • Anton I. Sipos

  • Ben +

  • Ben North +

  • Bran Yang +

  • Chris

  • Chris Carroux +

  • Christopher C. Aycock +

  • Christopher Scanlin +

  • Cody +

  • Da Wang +

  • Daniel Grady +

  • Dorozhko Anton +

  • Dr-Irv +

  • Erik M. Bray +

  • Evan Wright

  • Francis T. O’Donovan +

  • Frank Cleary +

  • Gianluca Rossi

  • Graham Jeffries +

  • Guillaume Horel

  • Henry Hammond +

  • Isaac Schwabacher +

  • Jean-Mathieu Deschenes

  • Jeff Reback

  • Joe Jevnik +

  • John Freeman +

  • John Fremlin +

  • Jonas Hoersch +

  • Joris Van den Bossche

  • Joris Vankerschaver

  • Justin Lecher

  • Justin Lin +

  • Ka Wo Chen

  • Keming Zhang +

  • Kerby Shedden

  • Kyle +

  • Marco Farrugia +

  • MasonGallo +

  • MattRijk +

  • Matthew Lurie +

  • Maximilian Roos

  • Mayank Asthana +

  • Mortada Mehyar

  • Moussa Taifi +

  • Navreet Gill +

  • Nicolas Bonnotte

  • Paul Reiners +

  • Philip Gura +

  • Pietro Battiston

  • RahulHP +

  • Randy Carnevale

  • Rinoc Johnson

  • Rishipuri +

  • Sangmin Park +

  • Scott E Lasley

  • Sereger13 +

  • Shannon Wang +

  • Skipper Seabold

  • Thierry Moisan

  • Thomas A Caswell

  • Toby Dylan Hocking +

  • Tom Augspurger

  • Travis +

  • Trent Hauck

  • Tux1

  • Varun

  • Wes McKinney

  • Will Thompson +

  • Yoav Ram

  • Yoong Kang Lim +

  • Yoshiki Vázquez Baeza

  • Young Joong Kim +

  • Younggun Kim

  • Yuval Langer +

  • alex argunov +

  • behzad nouri

  • boombard +

  • brian-pantano +

  • chromy +

  • daniel +

  • dgram0 +

  • gfyoung +

  • hack-c +

  • hcontrast +

  • jfoo +

  • kaustuv deolal +

  • llllllllll

  • ranarag +

  • rockg

  • scls19fr

  • seales +

  • sinhrks

  • srib +

  • surveymedia.ca +

  • tworec +