版本 0.18.1 (2016年5月3日)#

这是从0.18.0版本的一个小错误修复版本,包括大量错误修复以及一些新功能、增强功能和性能改进。我们建议所有用户升级到此版本。

亮点包括:

  • .groupby(...) 已经增强,在使用 .rolling(..).expanding(..).resample(..) 按组操作时提供了方便的语法,详见 这里

  • pd.to_datetime() 已经获得了从 DataFrame 组装日期的能力,请参见 这里

  • 方法链改进,见 这里

  • 自定义营业时间偏移,请参见 这里

  • 在处理 sparse 时修复了许多错误,请参见 这里

  • 扩展了 教程部分 ,增加了关于现代 pandas 的特性,感谢 @TomAugsburger 的贡献。(GH 13045)。

新功能#

自定义营业时间#

CustomBusinessHourBusinessHourCustomBusinessDay 的混合体,它允许你指定任意假期。详情请参见 自定义营业时间 (GH 11514)

In [1]: from pandas.tseries.offsets import CustomBusinessHour

In [2]: from pandas.tseries.holiday import USFederalHolidayCalendar

In [3]: bhour_us = CustomBusinessHour(calendar=USFederalHolidayCalendar())

马丁·路德·金纪念日前一天

In [4]: import datetime

In [5]: dt = datetime.datetime(2014, 1, 17, 15)

In [6]: dt + bhour_us
Out[6]: Timestamp('2014-01-17 16:00:00')

马丁·路德·金纪念日后的星期二(星期一跳过,因为是假日)

In [7]: dt + bhour_us * 2
Out[7]: Timestamp('2014-01-20 09:00:00')

方法 .groupby(..) 语法与窗口和重采样操作#

.groupby(...) 已经增强,在使用 .rolling(..).expanding(..).resample(..) 按组操作时提供方便的语法,参见 (GH 12486, GH 12738)。

你现在可以在 groupbys 上使用 .rolling(..).expanding(..) 方法。这些方法返回另一个延迟对象(类似于 .rolling().expanding() 在未分组的 pandas 对象上的行为)。然后,你可以以类似的方式对这些 RollingGroupby 对象进行操作。

之前,你必须这样做才能获得每个组的滚动窗口平均值:

In [8]: df = pd.DataFrame({"A": [1] * 20 + [2] * 12 + [3] * 8, "B": np.arange(40)})

In [9]: df
Out[9]: 
    A   B
0   1   0
1   1   1
2   1   2
3   1   3
4   1   4
.. ..  ..
35  3  35
36  3  36
37  3  37
38  3  38
39  3  39

[40 rows x 2 columns]
In [1]: df.groupby("A").apply(lambda x: x.rolling(4).B.mean())
Out[1]:
A
1  0      NaN
   1      NaN
   2      NaN
   3      1.5
   4      2.5
   5      3.5
   6      4.5
   7      5.5
   8      6.5
   9      7.5
   10     8.5
   11     9.5
   12    10.5
   13    11.5
   14    12.5
   15    13.5
   16    14.5
   17    15.5
   18    16.5
   19    17.5
2  20     NaN
   21     NaN
   22     NaN
   23    21.5
   24    22.5
   25    23.5
   26    24.5
   27    25.5
   28    26.5
   29    27.5
   30    28.5
   31    29.5
3  32     NaN
   33     NaN
   34     NaN
   35    33.5
   36    34.5
   37    35.5
   38    36.5
   39    37.5
Name: B, dtype: float64

现在你可以这样做:

In [10]: df.groupby("A").rolling(4).B.mean()
Out[10]: 
A    
1  0      NaN
   1      NaN
   2      NaN
   3      1.5
   4      2.5
         ... 
3  35    33.5
   36    34.5
   37    35.5
   38    36.5
   39    37.5
Name: B, Length: 40, dtype: float64

对于 .resample(..) 类型的操作,以前你必须:

In [11]: df = pd.DataFrame(
   ....:     {
   ....:         "date": pd.date_range(start="2016-01-01", periods=4, freq="W"),
   ....:         "group": [1, 1, 2, 2],
   ....:         "val": [5, 6, 7, 8],
   ....:     }
   ....: ).set_index("date")
   ....: 

In [12]: df
Out[12]: 
            group  val
date                  
2016-01-03      1    5
2016-01-10      1    6
2016-01-17      2    7
2016-01-24      2    8

[4 rows x 2 columns]
In[1]: df.groupby("group").apply(lambda x: x.resample("1D").ffill())
Out[1]:
                  group  val
group date
1     2016-01-03      1    5
      2016-01-04      1    5
      2016-01-05      1    5
      2016-01-06      1    5
      2016-01-07      1    5
      2016-01-08      1    5
      2016-01-09      1    5
      2016-01-10      1    6
2     2016-01-17      2    7
      2016-01-18      2    7
      2016-01-19      2    7
      2016-01-20      2    7
      2016-01-21      2    7
      2016-01-22      2    7
      2016-01-23      2    7
      2016-01-24      2    8

现在你可以这样做:

In[1]: df.groupby("group").resample("1D").ffill()
Out[1]:
                  group  val
group date
1     2016-01-03      1    5
      2016-01-04      1    5
      2016-01-05      1    5
      2016-01-06      1    5
      2016-01-07      1    5
      2016-01-08      1    5
      2016-01-09      1    5
      2016-01-10      1    6
2     2016-01-17      2    7
      2016-01-18      2    7
      2016-01-19      2    7
      2016-01-20      2    7
      2016-01-21      2    7
      2016-01-22      2    7
      2016-01-23      2    7
      2016-01-24      2    8

方法链改进#

以下方法/索引器现在接受一个 callable。这是为了使这些在方法链中更加有用,请参阅 文档。 (GH 11485, GH 12533)

  • .where().mask()

  • .loc[], iloc[].ix[]

  • [] 索引

方法 .where().mask()#

这些可以接受一个可调用的条件和 other 参数。

In [13]: df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9]})

In [14]: df.where(lambda x: x > 4, lambda x: x + 10)
Out[14]: 
    A   B  C
0  11  14  7
1  12   5  8
2  13   6  9

[3 rows x 3 columns]

方法 .loc[], .iloc[], .ix[]#

这些可以接受一个可调用对象,以及一个作为分片器的可调用对象元组。可调用对象可以返回一个有效的布尔索引器或任何这些索引器输入有效的内容。

# callable returns bool indexer
In [15]: df.loc[lambda x: x.A >= 2, lambda x: x.sum() > 10]
Out[15]: 
   B  C
1  5  8
2  6  9

[2 rows x 2 columns]

# callable returns list of labels
In [16]: df.loc[lambda x: [1, 2], lambda x: ["A", "B"]]
Out[16]: 
   A  B
1  2  5
2  3  6

[2 rows x 2 columns]

使用 [] 进行索引#

最后,你可以在 Series、DataFrame 和 Panel 的 [] 索引中使用可调用对象。可调用对象必须返回一个根据其类和索引类型有效的 [] 索引输入。

In [17]: df[lambda x: "A"]
Out[17]: 
0    1
1    2
2    3
Name: A, Length: 3, dtype: int64

使用这些方法 / 索引器,您可以在不使用临时变量的情况下链接数据选择操作。

In [18]: bb = pd.read_csv("data/baseball.csv", index_col="id")

In [19]: (bb.groupby(["year", "team"]).sum(numeric_only=True).loc[lambda df: df.r > 100])
Out[19]: 
           stint    g    ab    r    h  X2b  X3b  hr    rbi    sb   cs   bb     so   ibb   hbp    sh    sf  gidp
year team                                                                                                      
2007 CIN       6  379   745  101  203   35    2  36  125.0  10.0  1.0  105  127.0  14.0   1.0   1.0  15.0  18.0
     DET       5  301  1062  162  283   54    4  37  144.0  24.0  7.0   97  176.0   3.0  10.0   4.0   8.0  28.0
     HOU       4  311   926  109  218   47    6  14   77.0  10.0  4.0   60  212.0   3.0   9.0  16.0   6.0  17.0
     LAN      11  413  1021  153  293   61    3  36  154.0   7.0  5.0  114  141.0   8.0   9.0   3.0   8.0  29.0
     NYN      13  622  1854  240  509  101    3  61  243.0  22.0  4.0  174  310.0  24.0  23.0  18.0  15.0  48.0
     SFN       5  482  1305  198  337   67    6  40  171.0  26.0  7.0  235  188.0  51.0   8.0  16.0   6.0  41.0
     TEX       2  198   729  115  200   40    4  28  115.0  21.0  4.0   73  140.0   4.0   5.0   2.0   8.0  16.0
     TOR       4  459  1408  187  378   96    2  58  223.0   4.0  2.0  190  265.0  16.0  12.0   4.0  16.0  38.0

[8 rows x 18 columns]

当作为 MultiIndex 的一部分时,对 DatetimeIndex 进行部分字符串索引#

DateTimeIndexMultiIndex 的一部分时,部分字符串索引现在可以匹配 (GH 10331)

In [20]: dft2 = pd.DataFrame(
   ....:     np.random.randn(20, 1),
   ....:     columns=["A"],
   ....:     index=pd.MultiIndex.from_product(
   ....:         [pd.date_range("20130101", periods=10, freq="12H"), ["a", "b"]]
   ....:     ),
   ....: )
   ....:

In [21]: dft2
Out[21]:
                              A
2013-01-01 00:00:00 a  0.469112
                    b -0.282863
2013-01-01 12:00:00 a -1.509059
                    b -1.135632
2013-01-02 00:00:00 a  1.212112
...                         ...
2013-01-04 12:00:00 b  0.271860
2013-01-05 00:00:00 a -0.424972
                    b  0.567020
2013-01-05 12:00:00 a  0.276232
                    b -1.087401

[20 rows x 1 columns]

In [22]: dft2.loc["2013-01-05"]
Out[22]:
                              A
2013-01-05 00:00:00 a -0.424972
                    b  0.567020
2013-01-05 12:00:00 a  0.276232
                    b -1.087401

[4 rows x 1 columns]

在其他层级

In [26]: idx = pd.IndexSlice

In [27]: dft2 = dft2.swaplevel(0, 1).sort_index()

In [28]: dft2
Out[28]:
                              A
a 2013-01-01 00:00:00  0.469112
  2013-01-01 12:00:00 -1.509059
  2013-01-02 00:00:00  1.212112
  2013-01-02 12:00:00  0.119209
  2013-01-03 00:00:00 -0.861849
...                         ...
b 2013-01-03 12:00:00  1.071804
  2013-01-04 00:00:00 -0.706771
  2013-01-04 12:00:00  0.271860
  2013-01-05 00:00:00  0.567020
  2013-01-05 12:00:00 -1.087401

[20 rows x 1 columns]

In [29]: dft2.loc[idx[:, "2013-01-05"], :]
Out[29]:
                              A
a 2013-01-05 00:00:00 -0.424972
  2013-01-05 12:00:00  0.276232
b 2013-01-05 00:00:00  0.567020
  2013-01-05 12:00:00 -1.087401

[4 rows x 1 columns]

组装日期时间#

pd.to_datetime() 已经获得了从传入的 DataFrame 或字典中组装日期时间的能力。(GH 8158)。

In [20]: df = pd.DataFrame(
   ....:     {"year": [2015, 2016], "month": [2, 3], "day": [4, 5], "hour": [2, 3]}
   ....: )
   ....: 

In [21]: df
Out[21]: 
   year  month  day  hour
0  2015      2    4     2
1  2016      3    5     3

[2 rows x 4 columns]

使用传递的框架进行组装。

In [22]: pd.to_datetime(df)
Out[22]: 
0   2015-02-04 02:00:00
1   2016-03-05 03:00:00
Length: 2, dtype: datetime64[ns]

你可以只传递你需要组装的列。

In [23]: pd.to_datetime(df[["year", "month", "day"]])
Out[23]: 
0   2015-02-04
1   2016-03-05
Length: 2, dtype: datetime64[s]

其他增强功能#

  • pd.read_csv() 现在支持 delim_whitespace=True 用于 Python 引擎 (GH 12958)

  • pd.read_csv() 现在支持通过扩展推断或显式 compression='zip' 打开包含单个 CSV 的 ZIP 文件(GH 12175

  • pd.read_csv() 现在支持通过扩展推断或明确指定 compression='xz' 来使用 xz 压缩打开文件;DataFrame.to_csv 也以相同的方式支持 xz 压缩 (GH 11852)

  • pd.read_msgpack() 现在即使在使用了压缩的情况下,也总是提供可写的 ndarrays (GH 12359)。

  • pd.read_msgpack() 现在支持使用 msgpack 序列化和反序列化分类数据 (GH 12573)

  • .to_json() 现在支持包含分类和稀疏数据的 NDFrames (GH 10778)

  • interpolate() 现在支持 method='akima' (GH 7588)。

  • pd.read_excel() 现在接受路径对象(例如 pathlib.Path, py.path.local)作为文件路径,与其他 read_* 函数保持一致 (GH 12655)

  • DatetimeIndex.dt 访问器中添加了 .weekday_name 属性作为组件。(GH 11128)

  • Index.take 现在一致处理 allow_fillfill_value (GH 12631)

    In [24]: idx = pd.Index([1.0, 2.0, 3.0, 4.0], dtype="float")
    
    # default, allow_fill=True, fill_value=None
    In [25]: idx.take([2, -1])
    Out[25]: Index([3.0, 4.0], dtype='float64')
    
    In [26]: idx.take([2, -1], fill_value=True)
    Out[26]: Index([3.0, nan], dtype='float64')
    
  • Index 现在支持 .str.get_dummies() ,它返回 MultiIndex ,请参见 创建指示变量 (GH 10008, GH 10103)

    In [27]: idx = pd.Index(["a|b", "a|c", "b|c"])
    
    In [28]: idx.str.get_dummies("|")
    Out[28]: 
    MultiIndex([(1, 1, 0),
                (1, 0, 1),
                (0, 1, 1)],
               names=['a', 'b', 'c'])
    
  • pd.crosstab() 获得了一个 normalize 参数,用于规范化频率表 (GH 12569)。更新文档中的示例 在此

  • .resample(..).interpolate() 现在支持 (GH 12925)

  • .isin() 现在接受传递的 集合 (GH 12988)

稀疏变化#

这些更改使稀疏处理符合要求以返回正确的类型,并努力使索引体验更加流畅。

SparseArray.take 现在对标量输入返回标量,对其他输入返回 SparseArray。此外,它以与 Index 相同的规则处理负索引器 (GH 10560, GH 12796)

s = pd.SparseArray([np.nan, np.nan, 1, 2, 3, np.nan, 4, 5, np.nan, 6])
s.take(0)
s.take([1, 2, 3])
  • SparseSeries[] 中使用 Ellipsis 进行索引时出现 KeyError 错误 (GH 9467)

  • SparseArray[] 使用元组索引的错误未被正确处理 (GH 12966)

  • SparseSeries.loc[] 中类似列表输入的错误引发 TypeError (GH 10560)

  • SparseSeries.iloc[] 中使用标量输入可能会引发 IndexError (GH 10560)

  • SparseSeries.loc[], .iloc[] 中的错误,使用 slice 返回 SparseArray,而不是 SparseSeries (GH 10560)

  • SparseDataFrame.loc[], .iloc[] 中的错误可能导致密集的 Series,而不是 SparseSeries (GH 12787)

  • SparseArray 加法中的错误忽略了右侧的 fill_value (GH 12910)

  • SparseArray 模块中的错误引发 AttributeError (GH 12910)

  • SparseArray 中的 pow 错误将 1 ** np.nan 计算为 np.nan,这必须是 1 (GH 12910)

  • SparseArray 比较输出的错误可能导致不正确的结果或引发 ValueError (GH 12971)

  • SparseSeries.__repr__ 的长度超过 max_rows 时,会引发 TypeError (GH 10560)

  • SparseSeries.shape 中的错误忽略了 fill_value (GH 10452)

  • SparseSeriesSparseArray 中的错误可能与其密集值具有不同的 dtype (GH 12908)

  • SparseSeries.reindex 中的错误不正确处理 fill_value (GH 12797)

  • SparseArray.to_frame() 中的错误导致 DataFrame,而不是 SparseDataFrame (GH 9850)

  • SparseSeries.value_counts() 中的错误不会计算 fill_value (GH 6749)

  • SparseArray.to_dense() 中的错误不会保留 dtype (GH 10648)

  • SparseArray.to_dense() 中的错误不正确处理 fill_value (GH 12797)

  • pd.concat() 中的 SparseSeries 错误导致密集 (GH 10536)

  • pd.concat() 中的 SparseDataFrame 错误处理 fill_value 的 Bug (GH 9765)

  • SparseDataFramepd.concat() 中的错误可能会引发 AttributeError (GH 12174)

  • SparseArray.shift() 中的错误可能会引发 NameErrorTypeError (GH 12908)

API 变化#

方法 .groupby(..).nth() 更改#

.groupby(..).nth() 输出中的索引在传递 as_index 参数时现在更加一致 (GH 11039):

In [29]: df = pd.DataFrame({"A": ["a", "b", "a"], "B": [1, 2, 3]})

In [30]: df
Out[30]: 
   A  B
0  a  1
1  b  2
2  a  3

[3 rows x 2 columns]

之前的行为:

In [3]: df.groupby('A', as_index=True)['B'].nth(0)
Out[3]:
0    1
1    2
Name: B, dtype: int64

In [4]: df.groupby('A', as_index=False)['B'].nth(0)
Out[4]:
0    1
1    2
Name: B, dtype: int64

新行为:

In [31]: df.groupby("A", as_index=True)["B"].nth(0)
Out[31]: 
0    1
1    2
Name: B, Length: 2, dtype: int64

In [32]: df.groupby("A", as_index=False)["B"].nth(0)
Out[32]: 
0    1
1    2
Name: B, Length: 2, dtype: int64

此外,以前,一个 .groupby 总是会排序,无论是否传递了 sort=False.nth()

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

In [34]: df = pd.DataFrame(np.random.randn(100, 2), columns=["a", "b"])

In [35]: df["c"] = np.random.randint(0, 4, 100)

之前的行为:

In [4]: df.groupby('c', sort=True).nth(1)
Out[4]:
          a         b
c
0 -0.334077  0.002118
1  0.036142 -2.074978
2 -0.720589  0.887163
3  0.859588 -0.636524

In [5]: df.groupby('c', sort=False).nth(1)
Out[5]:
          a         b
c
0 -0.334077  0.002118
1  0.036142 -2.074978
2 -0.720589  0.887163
3  0.859588 -0.636524

新行为:

In [36]: df.groupby("c", sort=True).nth(1)
Out[36]: 
           a         b  c
2  -0.720589  0.887163  2
3   0.859588 -0.636524  3
7  -0.334077  0.002118  0
21  0.036142 -2.074978  1

[4 rows x 3 columns]

In [37]: df.groupby("c", sort=False).nth(1)
Out[37]: 
           a         b  c
2  -0.720589  0.887163  2
3   0.859588 -0.636524  3
7  -0.334077  0.002118  0
21  0.036142 -2.074978  1

[4 rows x 3 columns]

NumPy 函数兼容性#

通过增强 pandas 方法的签名,使其能够接受从 numpy 传递的参数,即使这些参数在 pandas 实现中不一定被使用,pandas 类数组方法(例如 sumtake)与其 numpy 对应方法之间的兼容性得到了极大的提高 (GH 12644, GH 12638, GH 12687)

  • IndexTimedeltaIndex.searchsorted() 现在接受一个 sorter 参数,以保持与 numpy 的 searchsorted 函数的兼容性 (GH 12238)

  • np.round()Series 上的 numpy 兼容性问题 (GH 12600)

这种签名增强的一个例子如下所示:

sp = pd.SparseDataFrame([1, 2, 3])
sp

之前的行为:

In [2]: np.cumsum(sp, axis=0)
...
TypeError: cumsum() takes at most 2 arguments (4 given)

新行为:

np.cumsum(sp, axis=0)

在 GroupBy 重采样上使用 .apply#

在使用 pd.TimeGrouper 的重新采样 groupby 操作中使用 apply 现在具有与在其他 groupby 操作中类似的 apply 调用相同的输出类型。(GH 11742)。

In [38]: df = pd.DataFrame(
   ....:     {"date": pd.to_datetime(["10/10/2000", "11/10/2000"]), "value": [10, 13]}
   ....: )
   ....: 

In [39]: df
Out[39]: 
        date  value
0 2000-10-10     10
1 2000-11-10     13

[2 rows x 2 columns]

之前的行为:

In [1]: df.groupby(pd.TimeGrouper(key='date',
   ...:                           freq='M')).apply(lambda x: x.value.sum())
Out[1]:
...
TypeError: cannot concatenate a non-NDFrame object

# Output is a Series
In [2]: df.groupby(pd.TimeGrouper(key='date',
   ...:                           freq='M')).apply(lambda x: x[['value']].sum())
Out[2]:
date
2000-10-31  value    10
2000-11-30  value    13
dtype: int64

新行为:

# Output is a Series
In [55]: df.groupby(pd.TimeGrouper(key='date',
    ...:                           freq='M')).apply(lambda x: x.value.sum())
Out[55]:
date
2000-10-31    10
2000-11-30    13
Freq: M, dtype: int64

# Output is a DataFrame
In [56]: df.groupby(pd.TimeGrouper(key='date',
    ...:                           freq='M')).apply(lambda x: x[['value']].sum())
Out[56]:
            value
date
2000-10-31     10
2000-11-30     13

read_csv 异常的变化#

为了标准化 cpython 引擎的 read_csv API,现在两者都会在遇到空列或标题时引发 EmptyDataError,这是 ValueError 的一个子类(GH 12493, GH 12506

之前的行为:

In [1]: import io

In [2]: df = pd.read_csv(io.StringIO(''), engine='c')
...
ValueError: No columns to parse from file

In [3]: df = pd.read_csv(io.StringIO(''), engine='python')
...
StopIteration

新行为:

In [1]: df = pd.read_csv(io.StringIO(''), engine='c')
...
pandas.io.common.EmptyDataError: No columns to parse from file

In [2]: df = pd.read_csv(io.StringIO(''), engine='python')
...
pandas.io.common.EmptyDataError: No columns to parse from file

除了这个错误更改外,还进行了其他几个更改:

  • CParserError 现在子类化 ValueError 而不是仅仅一个 Exception (GH 12551)

  • c 引擎无法解析列时,现在会引发 CParserError 而不是通用的 Exceptionread_csv 中 (GH 12506)

  • c 引擎在整数列中遇到 NaN 值时,read_csv 现在会引发 ValueError 而不是通用的 Exception (GH 12506)

  • true_values 被指定,并且 c 引擎在包含无法编码字节的列中遇到元素时,现在会引发 ValueError 而不是通用的 Exceptionread_csv 中 (GH 12506)

  • pandas.parser.OverflowError 异常已被移除,并被 Python 内置的 OverflowError 异常所取代 (GH 12506)

  • pd.read_csv() 不再允许 usecols 参数使用字符串和整数的组合 (GH 12678)

方法 to_datetime 错误更改#

在传递带有可转换条目的 uniterrors='coerce' 或不可转换的 errors='ignore' 时,pd.to_datetime() 中的错误。此外,当遇到该单位的超出范围值时,当 errors='raise' 时会引发 OutOfBoundsDateime 异常。(GH 11758, GH 13052, GH 13059)

之前的行为:

In [27]: pd.to_datetime(1420043460, unit='s', errors='coerce')
Out[27]: NaT

In [28]: pd.to_datetime(11111111, unit='D', errors='ignore')
OverflowError: Python int too large to convert to C long

In [29]: pd.to_datetime(11111111, unit='D', errors='raise')
OverflowError: Python int too large to convert to C long

新行为:

In [2]: pd.to_datetime(1420043460, unit='s', errors='coerce')
Out[2]: Timestamp('2014-12-31 16:31:00')

In [3]: pd.to_datetime(11111111, unit='D', errors='ignore')
Out[3]: 11111111

In [4]: pd.to_datetime(11111111, unit='D', errors='raise')
OutOfBoundsDatetime: cannot convert input with unit 'D'

其他 API 更改#

  • 对于 SeriesDataFramePanelMultiIndex.swaplevel() 现在为其前两个参数 ij 提供了默认值,这些默认值交换索引的两个最内层级别。(GH 12934)

  • IndexTimedeltaIndex.searchsorted() 现在接受一个 sorter 参数,以保持与 numpy 的 searchsorted 函数的兼容性 (GH 12238)

  • PeriodPeriodIndex 现在会引发继承自 ValueErrorIncompatibleFrequency 错误,而不是原始的 ValueError (GH 12615)

  • Series.apply 对于类别数据类型现在将传递的函数应用于每个 .categories``(而不是 ``.codes),并且在可能的情况下返回一个 category 数据类型 (GH 12473)

  • read_csv 现在如果 parse_dates 既不是布尔值、列表也不是字典,则会引发 ``TypeError``(与文档字符串匹配)(GH 5636)

  • .query()/.eval() 的默认值现在是 engine=None,如果安装了 numexpr,它将使用 numexpr;否则将回退到 python 引擎。这模仿了 0.18.1 版本之前的行为,如果安装了 numexpr(之前,如果未安装 numexpr,.query()/.eval() 会引发错误)。(GH 12749)

  • pd.show_versions() 现在包括 pandas_datareader 版本 (GH 12740)

  • 为泛型函数提供适当的 __name____qualname__ 属性 (GH 12021)

  • pd.concat(ignore_index=True) 现在默认使用 RangeIndex (GH 12695)

  • pd.merge()DataFrame.join() 在合并/连接单层与多层数据框时会显示 UserWarning (GH 9455, GH 12219)

  • scipy > 0.17 的兼容性,用于已弃用的 piecewise_polynomial 插值方法;支持替换的 from_derivatives 方法 (GH 12887)

弃用#

  • 方法名 Index.sym_diff() 已被弃用,可以用 Index.symmetric_difference() 替代 (GH 12591)

  • 方法名 Categorical.sort() 已被弃用,取而代之的是 Categorical.sort_values() (GH 12882)

性能提升#

  • 改进了 SAS 读取器的速度 (GH 12656, GH 12961)

  • .groupby(..).cumcount() 中的性能改进 (GH 11039)

  • 在使用 skiprows=an_integer 时,pd.read_csv() 的内存使用得到了改进 (GH 13005)

  • 改进了 DataFrame.to_sql 在检查表的区分大小写时的性能。现在仅在表名不是小写时检查表是否已正确创建。(GH 12876)

  • 改进了 Period 构造和时间序列绘图的性能 (GH 12903, GH 11831)。

  • 改进了 .str.encode().str.decode() 方法的性能 (GH 13008)

  • 如果输入是数值类型,to_numeric 的性能得到了提升 (GH 12777)

  • 改进了使用 IntIndex 进行稀疏算术的性能 (GH 13036)

错误修复#

  • pd.read_csv 中的 usecols 参数现在即使在 CSV 文件的行数不均匀时也会被尊重 (GH 12203)

  • 当指定 axis=1 时,groupby.transform(..) 中的错误与非单调有序索引 (GH 12713) 有关

  • PeriodPeriodIndex 创建中的错误在指定 freq="Minute" 时会引发 KeyError。注意,“Minute” 频率在 v0.17.0 中已被弃用,建议使用 freq="T" 代替 (GH 11854)。

  • PeriodIndex 中使用 .resample(...).count() 时总是引发 TypeError 的错误 (GH 12774)

  • .resample(...) 中使用 PeriodIndex 时,当为空时会转换为 DatetimeIndex 的错误 (GH 12868)

  • 在使用 PeriodIndex.resample(...) 中的错误,当重采样到现有频率时 (GH 12770)

  • 打印包含不同 freqPeriod 数据时出现 ValueError 错误 (GH 12615)

  • Categoricaldtype='category' 指定的情况下 Series 构造中的错误 (GH 12574)

  • 在与可强制转换的dtype连接时,错误过于激进,导致当对象长度超过 display.max_rows 时,输出格式中的dtypes不同 (GH 12411, GH 12045, GH 11594, GH 10571, GH 12211)

  • float_format 选项中的错误,选项未被验证为可调用对象。(GH 12706)

  • dropna=False 且没有组满足条件时 GroupBy.filter 中的错误 (GH 12768)

  • __name__.cum* 函数中的错误 (GH 12021)

  • Float64Inde/Int64Index 转换为 Int64Index.astype() 中的错误 (GH 12881)

  • .to_json()/.read_json() 中往返一个基于整数的索引时,当 ``orient=’index’``(默认)时出现的错误 (GH 12866)

  • 绘图 Categorical dtypes 中的错误导致尝试堆积条形图时出错 (GH 13019)

  • 与 >= numpy 1.11 的兼容性用于 NaT 比较 (GH 12969)

  • .drop() 中使用非唯一 MultiIndex 的错误。(GH 12701)

  • 在时区感知和朴素 DataFrame 的 .concat 中的错误 (GH 12467)

  • .resample(..).fillna(..) 中正确引发 ValueError 的错误,当传递一个非字符串时 (GH 12952)

  • pd.read_sas() 中的各种编码和头处理问题修复 (GH 12659, GH 12654, GH 12647, GH 12809)

  • pd.crosstab() 中的一个错误,当 values=None 时会静默忽略 aggfunc (GH 12569)。

  • 在序列化 datetime.time 时,DataFrame.to_json 可能出现段错误 (GH 11473)。

  • 在尝试序列化0d数组时,DataFrame.to_json 可能发生段错误 (GH 11299)。

  • 尝试序列化包含非ndarray值的 DataFrameSeries 时,在 to_json 中出现段错误;现在支持 categorysparsedatetime64[ns, tz] dtypes 的序列化 (GH 10778)。

  • DataFrame.to_json 中存在一个不支持的 dtype 未传递给默认处理程序的错误 (GH 12554)。

  • align 中的错误未返回子类 (GH 12983)

  • 在将 SeriesDataFrame 对齐时出现的错误 (GH 13037)

  • ABCPanel 中的一个错误,其中 Panel4D 未被视为此通用类型的有效实例 (GH 12810)

  • .groupby(..).apply(..) 案例中 .name 的一致性错误 (GH 12363)

  • Timestamp.__repr__ 中的错误导致在嵌套结构中 pprint 失败 (GH 12622)

  • Timedelta.minTimedelta.max 中的错误,这些属性现在报告了 pandas 识别的真实最小/最大 timedeltas。请参阅 文档。 (GH 12727)

  • .quantile() 中的插值错误可能会意外地强制转换为 float (GH 12772)

  • .quantile() 中使用空 Series 可能会返回标量而不是空 Series (GH 12772)

  • 在大型索引器中,.loc 的越界错误会引发 IndexError 而不是 KeyError (GH 12527)

  • 在使用 TimedeltaIndex.asfreq() 进行重采样时存在一个错误,之前不会包含最终的边界点 (GH 12926)

  • DataFrame 中使用 Categorical 进行相等性测试时的错误 (GH 12564)

  • GroupBy.first(), .last() 在使用 TimeGrouper 时返回不正确的行 (GH 7453)

  • 在使用 c 引擎时,当在引用的项目中指定带有换行符的 skiprows 时,pd.read_csv() 中的错误 (GH 10911, GH 12775)

  • 在分配带有对齐的时区感知日期时间 SeriesDataFrame 时区丢失的错误 (GH 12981)

  • normalize=Truedropna=True 时,.value_counts() 中的错误,其中空值仍然对归一化计数有贡献 (GH 12558)

  • Series.value_counts() 中的错误会在其 dtype 为 category 时丢失名称 (GH 12835)

  • Series.value_counts() 中的错误丢失时区信息 (GH 12835)

  • Categorical 中使用 Series.value_counts(normalize=True) 的错误引发 UnboundLocalError (GH 12835)

  • Panel.fillna() 中的错误忽略了 inplace=True (GH 12633)

  • 当同时指定 namesusecolsparse_dates 时,使用 c 引擎的 pd.read_csv() 中的 Bug (GH 9755)

  • 当同时指定 delim_whitespace=Truelineterminator 时,pd.read_csv() 中的错误(使用 c 引擎)(GH 12912)。

  • Series.renameDataFrame.renameDataFrame.rename_axis 中的错误,未将 Series 视为重新标记的映射 (GH 12623)。

  • .rolling.min.rolling.max 中清理以增强 dtype 处理 (GH 12373)

  • groupby 中复杂类型被强制转换为浮点数的错误 (GH 12902)

  • 如果 Series.map 的 dtype 是 category 或 tz-aware datetime,则引发 TypeError (GH 12473)

  • 32位平台上的某些测试比较的错误 (GH 12972)

  • 在从 RangeIndex 构造回退时的索引强制转换中的错误 (GH 12893)

  • 在窗口函数中传递无效参数(例如浮动窗口)时提供更好的错误消息 (GH 12669)

  • 在切片子类化的 DataFrame 中,定义为返回子类化的 Series 可能会返回正常的 Series (GH 11559)

  • .str 访问器方法中的错误可能会在输入有 name 且结果是 DataFrameMultiIndex 时引发 ValueError (GH 12617)

  • 在空帧上 DataFrame.last_valid_index()DataFrame.first_valid_index() 的错误 (GH 12800)

  • CategoricalIndex.get_loc 中的错误返回的结果与常规 Index 不同 (GH 12531)

  • PeriodIndex.resample 中的错误,名称未传播 (GH 12769)

  • date_range 中的 closed 关键字和时区存在问题 (GH 12684)。

  • 当输入数据包含时区感知的日期时间和时间增量时,pd.concat 中的错误会引发 AttributeError (GH 12620)

  • pd.concat 中的错误未能正确处理空 Series (GH 11082)

  • widthint 指定时,.plot.bar 对齐的错误 (GH 12979)

  • 如果二元运算符的参数是常量,则忽略 fill_value 中的错误 (GH 12723)

  • 在使用 bs4 风格解析带有标题和仅一列的表格时,pd.read_html() 中的错误 (GH 9178)

  • margins=Truedropna=True 时,.pivot_table 中的错误,其中空值仍然对边缘计数有贡献 (GH 12577)

  • dropna=False.pivot_table 中的错误,导致表格索引/列名消失 (GH 12133)

  • margins=Truedropna=False 时,pd.crosstab() 中的错误,该错误被提出 (GH 12642)

  • name 属性可以是可哈希类型时的 Series.name 中的错误 (GH 12610)

  • .describe() 中的错误会重置分类列信息 (GH 11558)

  • 在调用 resample().count() 时,loffset 参数未被应用的错误 (GH 12725)

  • pd.read_excel() 现在接受与关键字参数 names 关联的列名 (GH 12870)

  • pd.to_numeric()Index 的错误返回 np.ndarray ,而不是 Index (GH 12777)

  • pd.to_numeric() 中与类似日期时间的错误可能会引发 TypeError (GH 12777)

  • pd.to_numeric() 中使用标量引发 ValueError 的错误 (GH 12777)

贡献者#

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

  • Andrew Fiore-Gartland +

  • Bastiaan +

  • Benoît Vinot +

  • Brandon Rhodes +

  • DaCoEx +

  • Drew Fustin +

  • Ernesto Freitas +

  • Filip Ter +

  • Gregory Livschitz +

  • Gábor Lipták

  • Hassan Kibirige +

  • Iblis Lin

  • Israel Saeta Pérez +

  • Jason Wolosonovich +

  • Jeff Reback

  • Joe Jevnik

  • Joris Van den Bossche

  • Joshua Storck +

  • Ka Wo Chen

  • Kerby Shedden

  • Kieran O’Mahony

  • Leif Walsh +

  • Mahmoud Lababidi +

  • Maoyuan Liu +

  • Mark Roth +

  • Matt Wittmann

  • MaxU +

  • Maximilian Roos

  • Michael Droettboom +

  • Nick Eubank

  • Nicolas Bonnotte

  • OXPHOS +

  • Pauli Virtanen +

  • Peter Waller +

  • Pietro Battiston

  • Prabhjot Singh +

  • Robin Wilson

  • Roger Thomas +

  • Sebastian Bank

  • Stephen Hoover

  • Tim Hopper +

  • Tom Augspurger

  • WANG Aiyong

  • Wes Turner

  • Winand +

  • Xbar +

  • Yan Facai +

  • adneu +

  • ajenkins-cargometrics +

  • behzad nouri

  • chinskiy +

  • gfyoung

  • jeps-journal +

  • jonaslb +

  • kotrfa +

  • nileracecrew +

  • onesandzeroes

  • rs2 +

  • sinhrks

  • tsdlovell +