Pandas-2-2-中文文档-五十五-
Pandas 2.2 中文文档(五十五)
版本 0.18.1(2016 年 5 月 3 日)
这是从 0.18.0 的次要 bug 修复版本,包括大量的 bug 修复以及一些新功能、增强功能和性能改进。我们建议所有用户升级到此版本。
主要亮点包括:
-
.groupby(...)已得到加强,以提供与.rolling(..)、.expanding(..)和.resample(..)每个组的方便语法,参见此处 -
pd.to_datetime()现在可以从DataFrame组装日期,请参阅此处 -
方法链改进,请参阅此处。
-
自定义工作时间偏移,请参阅此处。
-
在处理
sparse时进行了许多 bug 修复,请参阅此处 -
通过@TomAugsburger提供的现代 pandas 功能,扩展了 Tutorials section。 (GH 13045).
v0.18.1 中的新功能
-
新特性
-
自定义工作时间
-
方法
.groupby(..)语法与窗口和重采样操作 -
方法链改进
-
方法
.where()和.mask()
-
-
在
DatetimeIndex的部分字符串索引时,作为MultiIndex的一部分 -
组装日期时间
-
其他增强功能
-
-
稀疏更改
-
API 更改
-
方法
.groupby(..).nth()更改 -
NumPy 函数兼容性
-
在 GroupBy 重采样上使用
.apply -
read_csv异常的更改 -
方法
to_datetime错误更改 -
其他 API 更改
-
弃用
-
-
性能改进
-
错误修复
-
贡献者
新特性
自定义工作时间
CustomBusinessHour 是 BusinessHour 和 CustomBusinessDay 的混合,允许您指定任意假期。详情请参阅自定义工作时间 (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())
MLK Day 前的星期五
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')
MLK Day 后的星期二(星期一因为是假日而跳过)
In [7]: dt + bhour_us * 2
Out[7]: Timestamp('2014-01-20 09:00:00')
``` ### 方法 `.groupby(..)` 语法与窗口和重采样操作
`.groupby(...)` 已增强以提供方便的语法,用于处理每个组的`.rolling(..)`、`.expanding(..)`和`.resample(..)`,请参阅 ([GH 12486](https://github.com/pandas-dev/pandas/issues/12486), [GH 12738](https://github.com/pandas-dev/pandas/issues/12738))。
现在你可以在 groupbys 上将`.rolling(..)`和`.expanding(..)`作为方法使用。 这些会返回另一个延迟对象(类似于在未分组的 pandas 对象上所做的`.rolling()`和`.expanding()`)。 然后,您可以以类似的方式操作这些`RollingGroupby`对象。
以前,要按组获得滚动窗口平均值,您必须执行以下操作:
```py
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](https://github.com/pandas-dev/pandas/issues/11485), [GH 12533](https://github.com/pandas-dev/pandas/issues/12533))
+ `.where()`和`.mask()`
+ `.loc[]`、`iloc[]`和`.ix[]`
+ `[]` 索引
#### 方法`.where()`和`.mask()`
这些可以接受条件和`other`参数的可调用对象。
```py
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 ... so ibb hbp sh sf gidp
year team ...
2007 CIN 6 379 745 101 203 35 ... 127.0 14.0 1.0 1.0 15.0 18.0
DET 5 301 1062 162 283 54 ... 176.0 3.0 10.0 4.0 8.0 28.0
HOU 4 311 926 109 218 47 ... 212.0 3.0 9.0 16.0 6.0 17.0
LAN 11 413 1021 153 293 61 ... 141.0 8.0 9.0 3.0 8.0 29.0
NYN 13 622 1854 240 509 101 ... 310.0 24.0 23.0 18.0 15.0 48.0
SFN 5 482 1305 198 337 67 ... 188.0 51.0 8.0 16.0 6.0 41.0
TEX 2 198 729 115 200 40 ... 140.0 4.0 5.0 2.0 8.0 16.0
TOR 4 459 1408 187 378 96 ... 265.0 16.0 12.0 4.0 16.0 38.0
[8 rows x 18 columns]
``` ### 部分字符串索引在`MultiIndex`中的部分`DatetimeIndex`
部分字符串索引现在在`MultiIndex`的一部分`DateTimeIndex`上匹配 ([GH 10331](https://github.com/pandas-dev/pandas/issues/10331))
```py
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](https://github.com/pandas-dev/pandas/issues/8158))。
```py
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[ns]
``` ### 其他增强
+ `pd.read_csv()` 现在支持`delim_whitespace=True`用于 Python 引擎 ([GH 12958](https://github.com/pandas-dev/pandas/issues/12958))
+ `pd.read_csv()` 现在支持打开包含单个 CSV 的 ZIP 文件,通过扩展推断或显式`compression='zip'` ([GH 12175](https://github.com/pandas-dev/pandas/issues/12175))
+ `pd.read_csv()` 现在支持使用 xz 压缩打开文件,通过扩展推断或明确指定`compression='xz'`; `xz` 压缩也通过相同的方式由`DataFrame.to_csv`支持 ([GH 11852](https://github.com/pandas-dev/pandas/issues/11852))
+ `pd.read_msgpack()` 现在即使使用压缩,也始终提供可写的 ndarrays([GH 12359](https://github.com/pandas-dev/pandas/issues/12359))
+ `pd.read_msgpack()` 现在支持使用 msgpack 序列化和反序列化分类变量([GH 12573](https://github.com/pandas-dev/pandas/issues/12573))
+ `.to_json()` 现在支持包含分类和稀疏数据的 `NDFrames`([GH 10778](https://github.com/pandas-dev/pandas/issues/10778))
+ `interpolate()` 现在支持 `method='akima'`([GH 7588](https://github.com/pandas-dev/pandas/issues/7588))。
+ `pd.read_excel()` 现在接受路径对象(例如 `pathlib.Path`, `py.path.local`)作为文件路径,与其他 `read_*` 函数一致([GH 12655](https://github.com/pandas-dev/pandas/issues/12655))
+ 已添加 `.weekday_name` 属性作为 `DatetimeIndex` 和 `.dt` 访问器的组成部分([GH 11128](https://github.com/pandas-dev/pandas/issues/11128))
+ `Index.take` 现在对 `allow_fill` 和 `fill_value` 的处理更加一致([GH 12631](https://github.com/pandas-dev/pandas/issues/12631))
```py
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](https://github.com/pandas-dev/pandas/issues/10008), [GH 10103](https://github.com/pandas-dev/pandas/issues/10103))
```py
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](https://github.com/pandas-dev/pandas/issues/12569))。更新文档中的示例在 这里。
+ `.resample(..).interpolate()` 现在受支持([GH 12925](https://github.com/pandas-dev/pandas/issues/12925))
+ `.isin()` 现在接受传递的 `sets`([GH 12988](https://github.com/pandas-dev/pandas/issues/12988)) ## 稀疏变化
这些变化使稀疏处理返回正确的类型,并努力使索引体验更加顺畅。
`SparseArray.take` 现在对标量输入返回标量,对其他输入返回 `SparseArray`。此外,它处理负索引器的规则与 `Index` 相同([GH 10560](https://github.com/pandas-dev/pandas/issues/10560), [GH 12796](https://github.com/pandas-dev/pandas/issues/12796))
```py
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[]中的 Bug 可能导致密集的Series,而不是SparseSeries(GH 12787) -
SparseArray中的加法 Bug 忽略了右侧的fill_value(GH 12910) -
SparseArraymod 中的 Bug 引发AttributeError(GH 12910) -
SparseArray中的 pow Bug 计算1 ** np.nan为np.nan,应为 1(GH 12910) -
SparseArray比较输出中的 Bug 可能会产生不正确的结果或引发ValueError(GH 12971) -
SparseSeries.__repr__中的 Bug 在长度超过max_rows时引发TypeError(GH 10560) -
SparseSeries.shape中的 Bug 忽略了fill_value(GH 10452) -
SparseSeries和SparseArray中的 Bug 可能与其密集值的dtype不同(GH 12908) -
SparseSeries.reindex中的 Bug 错误地处理了fill_value(GH 12797) -
SparseArray.to_frame()中的 Bug 导致了DataFrame,而不是SparseDataFrame(GH 9850) -
SparseSeries.value_counts()中的 Bug 不计算fill_value(GH 6749) -
SparseArray.to_dense()中的 Bug 不保留dtype(GH 10648) -
SparseArray.to_dense()中的 Bug 错误地处理了fill_value(GH 12797) -
SparseSeries的pd.concat()中的 Bug 导致结果是密集的(GH 10536) -
SparseDataFrame的pd.concat()中的 Bug 错误地处理了fill_value(GH 9765) -
SparseDataFrame的pd.concat()中的 Bug 可能引发AttributeError(GH 12174) -
SparseArray.shift()中的 Bug 可能会引发NameError或TypeError(GH 12908) ## API 变更
方法 .groupby(..).nth() 变更
当传递 as_index 参数时,.groupby(..).nth() 输出中的索引现在更加一致(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 总是会排序,无论是否使用 .nth() 传递了 sort=False。
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`数组方法(例如`sum`和`take`)与它们的`numpy`对应方法之间的兼容性([GH 12644](https://github.com/pandas-dev/pandas/issues/12644), [GH 12638](https://github.com/pandas-dev/pandas/issues/12638), [GH 12687](https://github.com/pandas-dev/pandas/issues/12687))
+ `Index`和`TimedeltaIndex`的`.searchsorted()`现在接受一个`sorter`参数,以保持与 numpy 的`searchsorted`函数的兼容性([GH 12238](https://github.com/pandas-dev/pandas/issues/12238))
+ 在`Series`上`np.round()`的 numpy 兼容性 bug([GH 12600](https://github.com/pandas-dev/pandas/issues/12600))
下面是一个签名增强的示例:
```py
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`进行重新采样分组操作(使用`apply`)时,现在具有与其他 groupby 操作上类似`apply`调用相同的输出类型。([GH 11742](https://github.com/pandas-dev/pandas/issues/11742)).
```py
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`异常更改
为了使`read_csv` API 在`c`和`python`引擎上标准化,现在两者在遇到空列或标题时都会引发`EmptyDataError`,这是`ValueError`的子类([GH 12493](https://github.com/pandas-dev/pandas/issues/12493), [GH 12506](https://github.com/pandas-dev/pandas/issues/12506))
先前行为:
```py
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引擎无法解析列时,在read_csv中现在会引发CParserError而不是通用的Exception(GH 12506) -
当
c引擎在整数列中遇到NaN值时,read_csv现在会引发ValueError而不是通用的Exception(GH 12506) -
当指定
true_values时,在c引擎遇到包含无法编码字节的列中的元素时,read_csv现在会引发ValueError而不是通用的Exception(GH 12506) -
pandas.parser.OverflowError异常已被移除,并已被 Python 内置的OverflowError异常替换(GH 12506) -
pd.read_csv()不再允许在usecols参数中组合字符串和整数(GH 12678) ###to_datetime方法错误更改
在传递可转换条目的 unit 和 errors='coerce' 或 errors='ignore' 时,pd.to_datetime() 中存在错误。此外,当遇到超出范围的值时,将引发 OutOfBoundsDateime 异常,errors='raise'。 (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 更改
+ 对于 `Series`、`DataFrame`、`Panel` 和 `MultiIndex` 的 `.swaplevel()` 现在具有其前两个参数 `i` 和 `j` 的默认值,这两个参数交换索引的最内层级别。 ([GH 12934](https://github.com/pandas-dev/pandas/issues/12934))
+ `.searchsorted()` 对于 `Index` 和 `TimedeltaIndex` 现在接受一个 `sorter` 参数,以保持与 numpy 的 `searchsorted` 函数的兼容性 ([GH 12238](https://github.com/pandas-dev/pandas/issues/12238))
+ `Period` 和 `PeriodIndex` 现在会引发 `IncompatibleFrequency` 错误,该错误继承自 `ValueError` 而不是原始的 `ValueError` ([GH 12615](https://github.com/pandas-dev/pandas/issues/12615))
+ `Series.apply` 对于类别 dtype 现在将传递的函数应用于每个 `.categories`(而不是 `.codes`),并在可能的情况下返回 `category` dtype ([GH 12473](https://github.com/pandas-dev/pandas/issues/12473))
+ 如果 `parse_dates` 不是布尔值、列表或字典(与文档字符串匹配),`read_csv` 现在会引发 `TypeError` ([GH 5636](https://github.com/pandas-dev/pandas/issues/5636))
+ `.query()/.eval()` 的默认值现在是 `engine=None`,如果安装了 `numexpr`,则会使用 `numexpr`;否则,它将回退到 `python` 引擎。这模仿了在 0.18.1 之前如果安装了 `numexpr` 的行为(以及以前,如果未安装 `numexpr`,`.query()/.eval()` 将引发异常)。 ([GH 12749](https://github.com/pandas-dev/pandas/issues/12749))
+ `pd.show_versions()` 现在包括 `pandas_datareader` 版本 ([GH 12740](https://github.com/pandas-dev/pandas/issues/12740))
+ 为通用函数提供适当的 `__name__` 和 `__qualname__` 属性 ([GH 12021](https://github.com/pandas-dev/pandas/issues/12021))
+ `pd.concat(ignore_index=True)` 现在默认使用 `RangeIndex` ([GH 12695](https://github.com/pandas-dev/pandas/issues/12695))
+ 当将单级与多级数据框合并/连接时,`pd.merge()` 和 `DataFrame.join()` 将显示 `UserWarning` 警告 ([GH 9455](https://github.com/pandas-dev/pandas/issues/9455), [GH 12219](https://github.com/pandas-dev/pandas/issues/12219))
+ 与 `scipy` > 0.17 兼容的已弃用的 `piecewise_polynomial` 插值方法;支持替换的 `from_derivatives` 方法 ([GH 12887](https://github.com/pandas-dev/pandas/issues/12887)) ### 弃用
+ 方法名 `Index.sym_diff()` 已弃用,可以用 `Index.symmetric_difference()` 替换 ([GH 12591](https://github.com/pandas-dev/pandas/issues/12591))
+ 方法名`Categorical.sort()`已被弃用,推荐使用`Categorical.sort_values()` ([GH 12882](https://github.com/pandas-dev/pandas/issues/12882)) ## 性能改进
+ 提升了 SAS 读取器的速度 ([GH 12656](https://github.com/pandas-dev/pandas/issues/12656), [GH 12961](https://github.com/pandas-dev/pandas/issues/12961))
+ 在`.groupby(..).cumcount()`中的性能改进 ([GH 11039](https://github.com/pandas-dev/pandas/issues/11039))
+ 在使用`skiprows=an_integer`时,改进了`pd.read_csv()`的内存使用情况 ([GH 13005](https://github.com/pandas-dev/pandas/issues/13005))
+ 在检查表的大小写敏感性时,改进了`DataFrame.to_sql`的性能。现在只有在表名不是小写时才检查表是否已正确创建。 ([GH 12876](https://github.com/pandas-dev/pandas/issues/12876))
+ 改进了`Period`构造和时间序列绘图的性能 ([GH 12903](https://github.com/pandas-dev/pandas/issues/12903), [GH 11831](https://github.com/pandas-dev/pandas/issues/11831))
+ 提升了`.str.encode()`和`.str.decode()`方法的性能 ([GH 13008](https://github.com/pandas-dev/pandas/issues/13008))
+ 如果输入是数值类型,则提升了`to_numeric`的性能 ([GH 12777](https://github.com/pandas-dev/pandas/issues/12777))
+ 通过`IntIndex`进行稀疏运算的性能改进 ([GH 13036](https://github.com/pandas-dev/pandas/issues/13036)) ## Bug 修复
+ 现在即使 CSV 文件的行数不均匀,`pd.read_csv`中的`usecols`参数也会被尊重 ([GH 12203](https://github.com/pandas-dev/pandas/issues/12203))
+ 当指定`axis=1`且具有非单调有序索引时,`groupby.transform(..)`中的 bug 已被修复 ([GH 12713](https://github.com/pandas-dev/pandas/issues/12713))
+ 如果指定`freq="Minute"`,则创建`Period`和`PeriodIndex`时会引发`KeyError`的 bug 已被修复。请注意,“Minute”频率在 v0.17.0 中已被弃用,建议改用`freq="T"` ([GH 11854](https://github.com/pandas-dev/pandas/issues/11854))
+ 在使用`PeriodIndex`时,`.resample(...).count()`总是引发`TypeError`的 bug 已被修复 ([GH 12774](https://github.com/pandas-dev/pandas/issues/12774))
+ 修复了当为空时,`.resample(...)`在将`PeriodIndex`转换为`DatetimeIndex`时的 bug ([GH 12868](https://github.com/pandas-dev/pandas/issues/12868))
+ 修复了在将`PeriodIndex`重新采样到现有频率时,`.resample(...)`中的 bug ([GH 12770](https://github.com/pandas-dev/pandas/issues/12770))
+ 包含不同`freq`的`Period`数据打印时引发`ValueError`的 bug 已被修复 ([GH 12615](https://github.com/pandas-dev/pandas/issues/12615))
+ 修复了当指定`dtype='category'`时,使用`Categorical`构造`Series`时的 bug ([GH 12574](https://github.com/pandas-dev/pandas/issues/12574))
+ 在具有可强制转换 dtype 的连接中存在错误,过于激进,导致当对象长于`display.max_rows`时,在输出格式化中出现不同的 dtype([GH 12411](https://github.com/pandas-dev/pandas/issues/12411), [GH 12045](https://github.com/pandas-dev/pandas/issues/12045), [GH 11594](https://github.com/pandas-dev/pandas/issues/11594), [GH 10571](https://github.com/pandas-dev/pandas/issues/10571), [GH 12211](https://github.com/pandas-dev/pandas/issues/12211))
+ 在`float_format`选项中,选项未被验证为可调用的错误。([GH 12706](https://github.com/pandas-dev/pandas/issues/12706))
+ 在`GroupBy.filter`中,当`dropna=False`且没有组满足条件时存在错误([GH 12768](https://github.com/pandas-dev/pandas/issues/12768))
+ 在`.cum*`函数的`__name__`中存在错误([GH 12021](https://github.com/pandas-dev/pandas/issues/12021))
+ 在将`Float64Inde/Int64Index`转换为`Int64Index`的`.astype()`中存在错误([GH 12881](https://github.com/pandas-dev/pandas/issues/12881))
+ 在`.to_json()/.read_json()`中整数索引的往返处理中存在错误,当`orient='index'`(默认)时([GH 12866](https://github.com/pandas-dev/pandas/issues/12866))
+ 在绘制`Categorical` dtypes 时,当尝试堆叠条形图时导致错误([GH 13019](https://github.com/pandas-dev/pandas/issues/13019))
+ 与`numpy` 1.11 兼容,用于`NaT`比较([GH 12969](https://github.com/pandas-dev/pandas/issues/12969))
+ 在具有非唯一`MultiIndex`的`.drop()`中存在的错误。([GH 12701](https://github.com/pandas-dev/pandas/issues/12701))
+ 在具有 datetime tz-aware 和 naive DataFrames 的`.concat`中存在错误([GH 12467](https://github.com/pandas-dev/pandas/issues/12467))
+ 在传递非字符串时,在`.resample(..).fillna(..)`中正确引发`ValueError`的错误([GH 12952](https://github.com/pandas-dev/pandas/issues/12952))
+ 在`pd.read_sas()`中存在各种编码和标题处理问题的错误修复([GH 12659](https://github.com/pandas-dev/pandas/issues/12659), [GH 12654](https://github.com/pandas-dev/pandas/issues/12654), [GH 12647](https://github.com/pandas-dev/pandas/issues/12647), [GH 12809](https://github.com/pandas-dev/pandas/issues/12809))
+ 在`pd.crosstab()`中,如果`values=None`,则会悄悄忽略`aggfunc`([GH 12569](https://github.com/pandas-dev/pandas/issues/12569)).
+ 在序列化`datetime.time`时,在`DataFrame.to_json`中存在潜在段错误([GH 11473](https://github.com/pandas-dev/pandas/issues/11473)).
+ 在尝试序列化 0d 数组时,在`DataFrame.to_json`中存在潜在段错误([GH 11299](https://github.com/pandas-dev/pandas/issues/11299)).
+ 在尝试序列化具有非 ndarray 值的`DataFrame`或`Series`时,在`to_json`中出现段错误;现在支持`category`、`sparse`和`datetime64[ns, tz]` dtypes 的序列化([GH 10778](https://github.com/pandas-dev/pandas/issues/10778))。
+ 在不支持的 dtype 未传递给默认处理程序的`DataFrame.to_json`中存在错误([GH 12554](https://github.com/pandas-dev/pandas/issues/12554)).
+ `.align` 中的 Bug,未返回子类 ([GH 12983](https://github.com/pandas-dev/pandas/issues/12983))
+ 将 `Series` 与 `DataFrame` 对齐时的 Bug ([GH 13037](https://github.com/pandas-dev/pandas/issues/13037))
+ `ABCPanel` 中的 Bug,`Panel4D` 未被视为该泛型类型的有效实例 ([GH 12810](https://github.com/pandas-dev/pandas/issues/12810))
+ `.groupby(..).apply(..)` 情况下 `.name` 的一致性 Bug ([GH 12363](https://github.com/pandas-dev/pandas/issues/12363))
+ `Timestamp.__repr__` 中的 Bug,导致嵌套结构中的 `pprint` 失败 ([GH 12622](https://github.com/pandas-dev/pandas/issues/12622))
+ `Timedelta.min` 和 `Timedelta.max` 中的 Bug,这些属性现在报告 pandas 认可的真正最小/最大 `timedeltas`。参见文档 ([GH 12727](https://github.com/pandas-dev/pandas/issues/12727))
+ `.quantile()` 中的 Bug,在插值时可能意外转换为 `float` ([GH 12772](https://github.com/pandas-dev/pandas/issues/12772))
+ `.quantile()` 中的 Bug,当 `Series` 为空时可能返回标量而不是空的 `Series` ([GH 12772](https://github.com/pandas-dev/pandas/issues/12772))
+ `.loc` 中的 Bug,在大型索引器中的越界会引发 `IndexError` 而不是 `KeyError` ([GH 12527](https://github.com/pandas-dev/pandas/issues/12527))
+ 在使用 `TimedeltaIndex` 和 `.asfreq()` 进行重新采样时的 Bug,以前不包括最后一个标杆点 ([GH 12926](https://github.com/pandas-dev/pandas/issues/12926))
+ 在 `DataFrame` 中使用 `Categorical` 进行相等性测试的 Bug ([GH 12564](https://github.com/pandas-dev/pandas/issues/12564))
+ `GroupBy.first()` 中的 Bug,当使用 `TimeGrouper` 时,`.last()` 返回错误行 ([GH 7453](https://github.com/pandas-dev/pandas/issues/7453))
+ 在使用 `c` 引擎的 `pd.read_csv()` 中,当在引号项中指定 `skiprows` 时出现换行符 ([GH 10911](https://github.com/pandas-dev/pandas/issues/10911), [GH 12775](https://github.com/pandas-dev/pandas/issues/12775))
+ `DataFrame` 在赋值时丢失时区信息的 Bug,当赋值为带时区信息的 datetime `Series` 时出现对齐问题 ([GH 12981](https://github.com/pandas-dev/pandas/issues/12981))
+ `.value_counts()` 中的 Bug,在 `normalize=True` 和 `dropna=True` 时,null 仍然会对规范化计数产生影响 ([GH 12558](https://github.com/pandas-dev/pandas/issues/12558))
+ `Series.value_counts()` 中的 Bug,在其 dtype 为 `category` 时会丢失名称 ([GH 12835](https://github.com/pandas-dev/pandas/issues/12835))
+ `Series.value_counts()` 中的 Bug,丢失时区信息 ([GH 12835](https://github.com/pandas-dev/pandas/issues/12835))
+ `Series.value_counts(normalize=True)` 中的 Bug,当 `Categorical` 时会引发 `UnboundLocalError` ([GH 12835](https://github.com/pandas-dev/pandas/issues/12835))
+ `Panel.fillna()` 中的 Bug,忽略了 `inplace=True` ([GH 12633](https://github.com/pandas-dev/pandas/issues/12633))
+ 在使用 `c` 引擎同时指定 `names`、`usecols` 和 `parse_dates` 时,`pd.read_csv()` 中的错误([GH 9755](https://github.com/pandas-dev/pandas/issues/9755))
+ 在使用 `c` 引擎同时指定 `delim_whitespace=True` 和 `lineterminator` 时,`pd.read_csv()` 中的错误([GH 12912](https://github.com/pandas-dev/pandas/issues/12912))
+ `Series.rename`、`DataFrame.rename` 和 `DataFrame.rename_axis` 中的错误,不将 `Series` 视为映射以重新标记([GH 12623](https://github.com/pandas-dev/pandas/issues/12623))
+ 在 `.rolling.min` 和 `.rolling.max` 中进行清理以增强 dtype 处理([GH 12373](https://github.com/pandas-dev/pandas/issues/12373))
+ 在 `groupby` 中,复杂类型被强制转换为浮点数的错误([GH 12902](https://github.com/pandas-dev/pandas/issues/12902))
+ 如果 `Series.map` 的 dtype 为 `category` 或 tz-aware `datetime`,则会引发 `TypeError` 的错误([GH 12473](https://github.com/pandas-dev/pandas/issues/12473))
+ 一些测试比较在 32 位平台上的错误([GH 12972](https://github.com/pandas-dev/pandas/issues/12972))
+ 从 `RangeIndex` 构造中回退时的索引强制转换错误([GH 12893](https://github.com/pandas-dev/pandas/issues/12893))
+ 在窗口函数中传递无效参数(例如浮点窗口)时提供更好的错误消息([GH 12669](https://github.com/pandas-dev/pandas/issues/12669))
+ 在定义为返回子类化 `Series` 的子类化 `DataFrame` 中切片时可能返回普通 `Series` 的错误([GH 11559](https://github.com/pandas-dev/pandas/issues/11559))
+ `.str` 访问器方法中的错误可能会在输入具有 `name` 且结果为 `DataFrame` 或 `MultiIndex` 时引发 `ValueError`([GH 12617](https://github.com/pandas-dev/pandas/issues/12617))
+ 在空框架上的 `DataFrame.last_valid_index()` 和 `DataFrame.first_valid_index()` 中的错误([GH 12800](https://github.com/pandas-dev/pandas/issues/12800))
+ `CategoricalIndex.get_loc` 中的错误返回与常规 `Index` 不同([GH 12531](https://github.com/pandas-dev/pandas/issues/12531))
+ `PeriodIndex.resample` 中的错误,名称未传播([GH 12769](https://github.com/pandas-dev/pandas/issues/12769))
+ `date_range` 中 `closed` 关键字和时区的错误([GH 12684](https://github.com/pandas-dev/pandas/issues/12684))
+ 当输入数据包含 tz-aware datetime 和 timedelta 时,`pd.concat` 中引发 `AttributeError` 的错误([GH 12620](https://github.com/pandas-dev/pandas/issues/12620))
+ `pd.concat` 未正确处理空 `Series` 的错误([GH 11082](https://github.com/pandas-dev/pandas/issues/11082))
+ 当使用 `int` 指定 `width` 时,`.plot.bar` 对齐的错误([GH 12979](https://github.com/pandas-dev/pandas/issues/12979))
+ 如果二元运算符的参数是常量,则忽略 `fill_value` 的错误([GH 12723](https://github.com/pandas-dev/pandas/issues/12723))
+ 使用 bs4 风格和解析具有标题和仅一列的表时,`pd.read_html()` 中的错误([GH 9178](https://github.com/pandas-dev/pandas/issues/9178))
+ 修复了当 `margins=True` 和 `dropna=True` 时 `.pivot_table` 中空值仍然会影响边际计数的错误([GH 12577](https://github.com/pandas-dev/pandas/issues/12577))
+ 修复了当 `dropna=False` 时 `.pivot_table` 中表索引/列名称消失的错误([GH 12133](https://github.com/pandas-dev/pandas/issues/12133))
+ 修复了当 `margins=True` 和 `dropna=False` 时 `pd.crosstab()` 中引发的错误([GH 12642](https://github.com/pandas-dev/pandas/issues/12642))
+ 修复了当 `name` 属性可以是可哈希类型时 `Series.name` 的错误([GH 12610](https://github.com/pandas-dev/pandas/issues/12610))
+ 修复了 `.describe()` 重置分类列信息的错误([GH 11558](https://github.com/pandas-dev/pandas/issues/11558))
+ 修复了在时间序列上调用 `resample().count()` 时未应用 `loffset` 参数的错误([GH 12725](https://github.com/pandas-dev/pandas/issues/12725))
+ `pd.read_excel()` 现在接受与关键字参数 `names` 关联的列名([GH 12870](https://github.com/pandas-dev/pandas/issues/12870))
+ 修复了 `pd.to_numeric()` 在返回 `np.ndarray` 而不是 `Index` 时的错误([GH 12777](https://github.com/pandas-dev/pandas/issues/12777))
+ 修复了 `pd.to_numeric()` 在类似日期时间的情况下可能引发 `TypeError` 的错误([GH 12777](https://github.com/pandas-dev/pandas/issues/12777))
+ 修复了当标量使用 `pd.to_numeric()` 时引发 `ValueError` 的错误([GH 12777](https://github.com/pandas-dev/pandas/issues/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
+ 王爱勇
+ Wes Turner
+ Winand +
+ Xbar +
+ Yan Facai +
+ adneu +
+ ajenkins-cargometrics +
+ behzad nouri
+ chinskiy +
+ gfyoung
+ jeps-journal +
+ jonaslb +
+ kotrfa +
+ nileracecrew +
+ onesandzeroes
+ rs2 +
+ sinhrks
+ tsdlovell + ## 新功能
### 自定义营业时间
`CustomBusinessHour` 是 `BusinessHour` 和 `CustomBusinessDay` 的混合体,允许您指定任意假期。详情请参阅自定义营业时间([GH 11514](https://github.com/pandas-dev/pandas/issues/11514))
```py
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](https://github.com/pandas-dev/pandas/issues/12486), [GH 12738](https://github.com/pandas-dev/pandas/issues/12738))。
你现在可以在分组上使用 `.rolling(..)` 和 `.expanding(..)` 作为方法。这些返回另一个延迟对象(类似于在未分组的 pandas 对象上所做的 `.rolling()` 和 `.expanding()`)。然后,你可以以类似的方式操作这些 `RollingGroupby` 对象。
以前,你必须这样做才能得到每个分组的滚动窗口均值:
```py
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](https://github.com/pandas-dev/pandas/issues/11485), [GH 12533](https://github.com/pandas-dev/pandas/issues/12533))
+ `.where()` 和 `.mask()`
+ `.loc[]`、`iloc[]` 和 `.ix[]`
+ `[]` 索引
#### 方法 `.where()` 和 `.mask()`
这些可以接受一个可调用函数作为条件和 `other` 参数。
```py
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 ... so ibb hbp sh sf gidp
year team ...
2007 CIN 6 379 745 101 203 35 ... 127.0 14.0 1.0 1.0 15.0 18.0
DET 5 301 1062 162 283 54 ... 176.0 3.0 10.0 4.0 8.0 28.0
HOU 4 311 926 109 218 47 ... 212.0 3.0 9.0 16.0 6.0 17.0
LAN 11 413 1021 153 293 61 ... 141.0 8.0 9.0 3.0 8.0 29.0
NYN 13 622 1854 240 509 101 ... 310.0 24.0 23.0 18.0 15.0 48.0
SFN 5 482 1305 198 337 67 ... 188.0 51.0 8.0 16.0 6.0 41.0
TEX 2 198 729 115 200 40 ... 140.0 4.0 5.0 2.0 8.0 16.0
TOR 4 459 1408 187 378 96 ... 265.0 16.0 12.0 4.0 16.0 38.0
[8 rows x 18 columns]
``` ### 在 `MultiIndex` 的一部分是 `DatetimeIndex` 上的部分字符串索引
部分字符串索引现在匹配 `MultiIndex` 的一部分是 `DateTimeIndex` ([GH 10331](https://github.com/pandas-dev/pandas/issues/10331))
```py
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](https://github.com/pandas-dev/pandas/issues/8158)).
```py
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[ns]
``` ### 其他增强
+ `pd.read_csv()` 现在支持 Python 引擎的 `delim_whitespace=True` ([GH 12958](https://github.com/pandas-dev/pandas/issues/12958))
+ `pd.read_csv()` 现在支持打开包含单个 CSV 的 ZIP 文件,通过扩展推断或明确指定 `compression='zip'` ([GH 12175](https://github.com/pandas-dev/pandas/issues/12175))
+ `pd.read_csv()` 现在支持使用 xz 压缩打开文件,通过扩展推断或明确指定 `compression='xz'`;`xz` 压缩也同样被 `DataFrame.to_csv` 支持,方式相同 ([GH 11852](https://github.com/pandas-dev/pandas/issues/11852))
+ `pd.read_msgpack()`现在即使使用压缩,也始终返回可写入的 ndarrays ([GH 12359](https://github.com/pandas-dev/pandas/issues/12359)).
+ `pd.read_msgpack()`现在支持使用 msgpack 序列化和反序列化分类变量 ([GH 12573](https://github.com/pandas-dev/pandas/issues/12573))
+ `.to_json()`现在支持包含分类和稀疏数据的`NDFrames` ([GH 10778](https://github.com/pandas-dev/pandas/issues/10778))
+ `interpolate()`现在支持`method='akima'` ([GH 7588](https://github.com/pandas-dev/pandas/issues/7588)).
+ `pd.read_excel()`现在接受路径对象(例如`pathlib.Path`、`py.path.local`)作为文件路径,与其他`read_*`函数保持一致 ([GH 12655](https://github.com/pandas-dev/pandas/issues/12655))
+ 添加了`.weekday_name`属性作为`DatetimeIndex`和`.dt`访问器的组成部分。 ([GH 11128](https://github.com/pandas-dev/pandas/issues/11128))
+ `Index.take`现在一致处理`allow_fill`和`fill_value` ([GH 12631](https://github.com/pandas-dev/pandas/issues/12631))
```py
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`,参见 Creating Indicator Variables ([GH 10008](https://github.com/pandas-dev/pandas/issues/10008), [GH 10103](https://github.com/pandas-dev/pandas/issues/10103))
```py
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](https://github.com/pandas-dev/pandas/issues/12569)). 更新文档中的示例在这里.
+ `.resample(..).interpolate()`现在受支持 ([GH 12925](https://github.com/pandas-dev/pandas/issues/12925))
+ `.isin()`现在接受传递的`sets` ([GH 12988](https://github.com/pandas-dev/pandas/issues/12988)) ### 自定义工作时间
`CustomBusinessHour`是`BusinessHour`和`CustomBusinessDay`的混合体,允许您指定任意假期。详情请参见 Custom Business Hour ([GH 11514](https://github.com/pandas-dev/pandas/issues/11514))
```py
In [1]: from pandas.tseries.offsets import CustomBusinessHour
In [2]: from pandas.tseries.holiday import USFederalHolidayCalendar
In [3]: bhour_us = CustomBusinessHour(calendar=USFederalHolidayCalendar())
MLK 日前的星期五
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')
MLK 日后的星期二(星期一被跳过,因为那是个假日)
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(..)作为方法。这些返回另一个延迟对象(类似于在未分组的 pandas 对象上执行的.rolling()和.expanding())。然后,您可以以类似的方式操作这些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 ... so ibb hbp sh sf gidp
year team ...
2007 CIN 6 379 745 101 203 35 ... 127.0 14.0 1.0 1.0 15.0 18.0
DET 5 301 1062 162 283 54 ... 176.0 3.0 10.0 4.0 8.0 28.0
HOU 4 311 926 109 218 47 ... 212.0 3.0 9.0 16.0 6.0 17.0
LAN 11 413 1021 153 293 61 ... 141.0 8.0 9.0 3.0 8.0 29.0
NYN 13 622 1854 240 509 101 ... 310.0 24.0 23.0 18.0 15.0 48.0
SFN 5 482 1305 198 337 67 ... 188.0 51.0 8.0 16.0 6.0 41.0
TEX 2 198 729 115 200 40 ... 140.0 4.0 5.0 2.0 8.0 16.0
TOR 4 459 1408 187 378 96 ... 265.0 16.0 12.0 4.0 16.0 38.0
[8 rows x 18 columns]
方法 .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 ... so ibb hbp sh sf gidp
year team ...
2007 CIN 6 379 745 101 203 35 ... 127.0 14.0 1.0 1.0 15.0 18.0
DET 5 301 1062 162 283 54 ... 176.0 3.0 10.0 4.0 8.0 28.0
HOU 4 311 926 109 218 47 ... 212.0 3.0 9.0 16.0 6.0 17.0
LAN 11 413 1021 153 293 61 ... 141.0 8.0 9.0 3.0 8.0 29.0
NYN 13 622 1854 240 509 101 ... 310.0 24.0 23.0 18.0 15.0 48.0
SFN 5 482 1305 198 337 67 ... 188.0 51.0 8.0 16.0 6.0 41.0
TEX 2 198 729 115 200 40 ... 140.0 4.0 5.0 2.0 8.0 16.0
TOR 4 459 1408 187 378 96 ... 265.0 16.0 12.0 4.0 16.0 38.0
[8 rows x 18 columns]
部分字符串索引在 DatetimeIndex 的一部分时
当作为 MultiIndex 的一部分时,部分字符串索引现在匹配 DateTimeIndex(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[ns]
其他增强
-
pd.read_csv()现在支持 Python 引擎的delim_whitespace=True(GH 12958)。 -
pd.read_csv()现在支持通过扩展推断或明确指定compression='zip'来打开包含单个 CSV 的 ZIP 文件(GH 12175)。 -
pd.read_csv()现在支持使用 xz 压缩打开文件,通过扩展推断或明确指定compression='xz';xz压缩也同样被DataFrame.to_csv支持(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) -
增加了
.weekday_name属性作为DatetimeIndex和.dt访问器的组成部分(GH 11128) -
Index.take现在一致地处理allow_fill和fill_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()现在接受传递的sets(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的 Bug(GH 9467) -
SparseArray[]对元组进行索引的 Bug 没有得到正确处理(GH 12966) -
SparseSeries.loc[]中出现列表类似输入时引发TypeError的 Bug(GH 10560) -
SparseSeries.iloc[]中出现标量输入可能引发IndexError的 Bug(GH 10560) -
SparseSeries.loc[]、.iloc[]中使用slice返回SparseArray,而不是SparseSeries的 Bug(GH 10560) -
SparseDataFrame.loc[]、.iloc[]中出现的 Bug 可能导致密集Series,而不是SparseSeries(GH 12787) -
SparseArray的加法中忽略右侧的fill_value的 Bug (GH 12910) -
SparseArray的 mod 函数中存在 Bug,会引发AttributeError(GH 12910) -
SparseArray的 pow 函数中存在 Bug,将1 ** np.nan计算为np.nan,应该是1(GH 12910) -
SparseArray比较输出的 Bug 可能会产生不正确的结果或引发ValueError(GH 12971) -
SparseSeries.__repr__中存在 Bug,当长度超过max_rows时会引发TypeError(GH 10560) -
SparseSeries.shape中存在 Bug,忽略了fill_value(GH 10452) -
SparseSeries和SparseArray中的 Bug 可能与其密集值的dtype不同 (GH 12908) -
SparseSeries.reindex中存在 Bug,不正确处理fill_value(GH 12797) -
SparseArray.to_frame()中存在 Bug,结果是DataFrame,而不是SparseDataFrame(GH 9850) -
SparseSeries.value_counts()中存在 Bug,不计算fill_value(GH 6749) -
SparseArray.to_dense()中存在 Bug,不保留dtype(GH 10648) -
SparseArray.to_dense()中不正确处理fill_value的 Bug (GH 12797) -
pd.concat()中的SparseSeries导致密集化的 Bug (GH 10536) -
pd.concat()中的SparseDataFrame不正确处理fill_value的 Bug (GH 9765) -
pd.concat()中的SparseDataFrame可能会引发AttributeError的 Bug (GH 12174) -
SparseArray.shift()中存在 Bug,可能会引发NameError或TypeError(GH 12908)
API 变更
方法 .groupby(..).nth() 变更
当传递 as_index 参数时,.groupby(..).nth() 输出的索引现在更加一致了 (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`数组方法(例如`sum`和`take`)与它们的`numpy`对应方法之间的兼容性。([GH 12644](https://github.com/pandas-dev/pandas/issues/12644), [GH 12638](https://github.com/pandas-dev/pandas/issues/12638), [GH 12687](https://github.com/pandas-dev/pandas/issues/12687))
+ `.searchsorted()`对于`Index`和`TimedeltaIndex`现在接受一个`sorter`参数,以保持与 numpy 的`searchsorted`函数的兼容性([GH 12238](https://github.com/pandas-dev/pandas/issues/12238))
+ 在`Series`上的`np.round()`的 numpy 兼容性中存在错误([GH 12600](https://github.com/pandas-dev/pandas/issues/12600))
一个此类签名增强的示例如下所示:
```py
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`
使用`apply`在重新采样分组操作(使用`pd.TimeGrouper`)上,现在具有与其他分组操作上类似的`apply`调用相同的输出类型。([GH 11742](https://github.com/pandas-dev/pandas/issues/11742))。
```py
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`异常的更改
为了使`read_csv` API 在`c`和`python`引擎上标准化,现在两者都将对空列或标题引发`EmptyDataError`,这是`ValueError`的子类。([GH 12493](https://github.com/pandas-dev/pandas/issues/12493), [GH 12506](https://github.com/pandas-dev/pandas/issues/12506))
先前行为:
```py
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引擎无法解析列时,在read_csv中现在会引发CParserError而不是通用的Exception(GH 12506) -
当
c引擎在整数列中遇到NaN值时,在read_csv中现在会引发ValueError而不是通用的Exception(GH 12506) -
当指定
true_values并且c引擎遇到包含不可编码字节的列中的元素时,在read_csv中现在会引发ValueError而不是通用的Exception(GH 12506) -
pandas.parser.OverflowError异常已被移除,并已被 Python 内置的OverflowError异常替换(GH 12506) -
pd.read_csv()不再允许在usecols参数中组合字符串和整数。(GH 12678) ### 方法to_datetime错误更改
在pd.to_datetime()中传递可转换条目和errors='coerce'或不可转换条目和errors='ignore'时存在错误。此外,当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 更改
+ 对于`Series`、`DataFrame`、`Panel`和`MultiIndex`的`.swaplevel()`现在具有其前两个参数`i`和`j`的默认值,这两个参数交换索引的最内层级别。([GH 12934](https://github.com/pandas-dev/pandas/issues/12934))
+ `.searchsorted()`对于`Index`和`TimedeltaIndex`现在接受一个`sorter`参数以保持与 numpy 的`searchsorted`函数的兼容性 ([GH 12238](https://github.com/pandas-dev/pandas/issues/12238))
+ `Period`和`PeriodIndex`现在引发`IncompatibleFrequency`错误,该错误继承自`ValueError`而不是原始的`ValueError` ([GH 12615](https://github.com/pandas-dev/pandas/issues/12615))
+ `Series.apply`对于类别 dtype 现在将传递的函数应用于每个`.categories`(而不是`.codes`),如果可能的话返回`category` dtype ([GH 12473](https://github.com/pandas-dev/pandas/issues/12473))
+ `read_csv`现在会在`parse_dates`既不是布尔值、列表或字典时引发`TypeError`(与文档字符串匹配)([GH 5636](https://github.com/pandas-dev/pandas/issues/5636))
+ `.query()/.eval()`的默认值现在是`engine=None`,如果安装了`numexpr`,则会使用`numexpr`;否则将回退到`python`引擎。如果安装了`numexpr`,则模仿了 0.18.1 之前的行为(以前,如果未安装`numexpr`,`.query()/.eval()`会引发异常)。([GH 12749](https://github.com/pandas-dev/pandas/issues/12749))
+ `pd.show_versions()`现在包括`pandas_datareader`版本 ([GH 12740](https://github.com/pandas-dev/pandas/issues/12740))
+ 为通用函数提供适当的`__name__`和`__qualname__`属性 ([GH 12021](https://github.com/pandas-dev/pandas/issues/12021))
+ `pd.concat(ignore_index=True)`现在默认使用`RangeIndex` ([GH 12695](https://github.com/pandas-dev/pandas/issues/12695))
+ 当将单级和多级数据框合并/连接时,`pd.merge()`和`DataFrame.join()`将显示`UserWarning` ([GH 9455](https://github.com/pandas-dev/pandas/issues/9455), [GH 12219](https://github.com/pandas-dev/pandas/issues/12219))
+ 与`scipy` > 0.17 兼容的已弃用的`piecewise_polynomial`插值方法;支持替代的`from_derivatives`方法 ([GH 12887](https://github.com/pandas-dev/pandas/issues/12887)) ### 弃用
+ 方法名`Index.sym_diff()`已弃用,可以替换为`Index.symmetric_difference()` ([GH 12591](https://github.com/pandas-dev/pandas/issues/12591))
+ 方法名 `Categorical.sort()` 已被弃用,推荐使用 `Categorical.sort_values()` ([GH 12882](https://github.com/pandas-dev/pandas/issues/12882)) ### 方法 `.groupby(..).nth()` 的变化
当传递 `as_index` 参数时,`.groupby(..).nth()` 输出中的索引现在更加一致 ([GH 11039](https://github.com/pandas-dev/pandas/issues/11039)):
```py
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 总是会排序,无论是否使用 .nth() 传递了 sort=False。
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 数组类方法(例如 sum 和 take)与它们的 numpy 对应方法之间的兼容性,通过增加 pandas 方法的签名,使其接受可以从 numpy 传递的参数,即使它们在 pandas 实现中并不一定会使用 (GH 12644, GH 12638, GH 12687)
-
.searchsorted()用于Index和TimedeltaIndex现在接受一个sorter参数,以保持与 numpy 的searchsorted函数的兼容性 (GH 12238) -
在
Series上np.round()的 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
在重采样 GroupBy 操作(使用 pd.TimeGrouper)上使用 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 异常的变化
为了使 c 和 python 引擎的 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引擎无法解析列时,read_csv现在会引发CParserError而不是一般的Exception(GH 12506) -
当
c引擎在整数列中遇到NaN值时,read_csv现在会引发ValueError而不是一般的Exception(GH 12506) -
当指定
true_values时,现在在read_csv中抛出ValueError而不是通用的Exception,并且c引擎在包含无法编码的字节的列中遇到一个元素时将会抛出异常(GH 12506) -
pandas.parser.OverflowError异常已被移除,并已被 Python 的内置OverflowError异常取代(GH 12506) -
pd.read_csv()现在不再允许在usecols参数中组合字符串和整数(GH 12678)
to_datetime 方法错误变更
在传递可转换条目的 unit 和 errors='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 变更
-
对于
Series、DataFrame、Panel和MultiIndex,.swaplevel()现在具有其前两个参数i和j的默认值,用于交换索引的两个最内层级别。(GH 12934) -
对于
Index和TimedeltaIndex,.searchsorted()现在接受一个sorter参数以保持与 numpy 的searchsorted函数的兼容性(GH 12238) -
Period和PeriodIndex现在引发IncompatibleFrequency错误,该错误继承自ValueError而不是原始的ValueError(GH 12615) -
Series.apply对于类别 dtype 现在将传递的函数应用于每个.categories(而不是.codes),并在可能的情况下返回一个categorydtype(GH 12473) -
如果
parse_dates不是布尔值、列表或字典(与文档字符串匹配),read_csv现在会引发TypeError(GH 5636) -
.query()/.eval()的默认值现在是engine=None,如果安装了numexpr,则会使用它;否则将退回到python引擎。如果安装了numexpr,则这模仿了 0.18.1 之前的行为(如果未安装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) -
对于已弃用的
piecewise_polynomial插值方法与scipy> 0.17 兼容;支持替代方法from_derivatives(GH 12887)
废弃
-
方法名
Index.sym_diff()已弃用,可替换为Index.symmetric_difference()(GH 12591) -
方法名
Categorical.sort()已弃用,改用Categorical.sort_values()(GH 12882)
性能改进
-
在
.groupby(..).cumcount()中的性能改进(GH 11039) -
在使用
skiprows=an_integer时,改进了pd.read_csv()的内存使用情况(GH 13005) -
在检查表的大小写敏感性时,改进了
DataFrame.to_sql的性能。现在只在表名不是小写时才检查表是否已正确创建。(GH 12876) -
改进了
.str.encode()和.str.decode()方法的性能(GH 13008) -
如果输入是数字类型,则改进了
to_numeric的性能(GH 12777) -
通过
IntIndex进行稀疏算术的性能改进(GH 13036)
错误修复
-
即使 CSV 文件的行数不均匀,
pd.read_csv中的usecols参数现在也会受到尊重(GH 12203) -
当指定
axis=1时,groupby.transform(..)中的错误(axis=1)与非单调有序索引一起使用时出现错误(GH 12713) -
如果指定
freq="Minute",则在Period和PeriodIndex创建中出现KeyError错误。请注意,“Minute”频率已在 v0.17.0 中弃用,建议改用freq="T"(GH 11854) -
始终引发
TypeError的.resample(...).count()与PeriodIndex一起使用的错误(GH 12774) -
当为空时,
.resample(...)与PeriodIndex转换为DatetimeIndex时的错误(GH 12868) -
当对 PeriodIndex 进行重采样到现有频率时,
.resample(...)存在 Bug(GH 12770) -
包含不同
freq的Period数据打印时引发ValueError的 Bug(GH 12615) -
在指定
dtype='category'的情况下,使用Categorical构建Series存在 Bug(GH 12574) -
当对象长于
display.max_rows时,具有可强制转换 dtype 的连接在输出格式化时过于激进,导致不同的 dtype(GH 12411, GH 12045, GH 11594, GH 10571, GH 12211) -
选项
float_format在未验证为可调用时出现的 Bug。(GH 12706) -
在
GroupBy.filter中,当dropna=False且没有组符合条件时存在 Bug (GH 12768) -
.cum*函数的__name__中存在 Bug(GH 12021) -
将
Float64Inde/Int64Index转换为Int64Index时存在 Bug 在.astype()中。 (GH 12881) -
在
.to_json()/.read_json()中,默认情况下orient='index',对整数型索引进行回环处理存在 Bug (GH 12866) -
在尝试堆叠条形图时,
Categorical数据类型绘图存在 Bug 导致错误(GH 13019) -
兼容
numpy版本1.11以上的NaT比较(GH 12969) -
在非唯一的
MultiIndex中使用.drop()存在 Bug。 (GH 12701) -
.concat方法在处理带时区和不带时区的 DataFrame 时存在 Bug(GH 12467) -
在传递非字符串时,在
.resample(..).fillna(..)中正确引发ValueError的 Bug(GH 12952) -
在
pd.read_sas()中存在各种编码和头部处理问题的 Bug 修复(GH 12659, GH 12654, GH 12647, GH 12809) -
在
pd.crosstab()中存在的 Bug:如果values=None,则会静默忽略aggfunc(GH 12569) -
在序列化
datetime.time时,在DataFrame.to_json中存在潜在的段错误(GH 11473) -
在尝试序列化 0d 数组时,
DataFrame.to_json中存在潜在的段错误 (GH 11299)。 -
在尝试序列化具有非 ndarray 值的
DataFrame或Series时,to_json中存在的段错误;现在支持category、sparse和datetime64[ns, tz]dtypes 的序列化 (GH 10778)。 -
DataFrame.to_json中存在的 Bug,不支持的 dtype 未传递给默认处理程序 (GH 12554)。 -
.align中存在的 Bug,未返回子类 (GH 12983)。 -
将
Series与DataFrame对齐时存在的 Bug (GH 13037)。 -
ABCPanel中存在的 Bug,其中Panel4D不被视为此通用类型的有效实例 (GH 12810)。 -
.groupby(..).apply(..)案例中.name一致性存在 Bug (GH 12363)。 -
导致
pprint在嵌套结构中失败的Timestamp.__repr__中存在的 Bug (GH 12622)。 -
Timedelta.min和Timedelta.max中存在的 Bug,现在的属性报告 pandas 认可的真实最小/最大timedeltas。参见 documentation。 (GH 12727)。 -
使用插值的
.quantile()中存在的 Bug,可能意外地强制转换为float(GH 12772)。 -
使用空
Series的.quantile()中存在的 Bug,可能返回标量而不是空Series(GH 12772)。 -
在大量索引器中越界的
.loc中存在的 Bug,会引发IndexError而不是KeyError(GH 12527)。 -
使用
TimedeltaIndex和.asfreq()重新采样时存在 Bug,之前不会包含最终的围栏。 (GH 12926)。 -
在
DataFrame中的Categorical中的相等性测试中存在 Bug (GH 12564)。 -
使用
TimeGrouper时,GroupBy.first()和.last()返回的行不正确 (GH 7453)。 -
使用
c引擎的pd.read_csv()中存在的 Bug,当在引号中的项中指定skiprows时存在新行 (GH 10911, GH 12775)。 -
在为具有对齐的时区感知日期时间
Series分配时存在的DataFrame时区丢失的 Bug (GH 12981)。 -
当
normalize=True和dropna=True时,.value_counts()存在 Bug,其中空值仍然影响了归一化计数 (GH 12558)。 -
当
Series的 dtype 为category时,在Series.value_counts()中存在错误,会丢失名称 (GH 12835) -
在
Series.value_counts()中存在错误,丢失时区信息 (GH 12835) -
在
Series.value_counts(normalize=True)与Categorical一起使用时,会引发UnboundLocalError(GH 12835) -
在
Panel.fillna()中存在错误,忽略了inplace=True(GH 12633) -
当同时使用
c引擎和names、usecols以及parse_dates来指定pd.read_csv()时出现错误 (GH 9755) -
当同时使用
c引擎和delim_whitespace=True以及lineterminator来指定pd.read_csv()时出现错误 (GH 12912) -
在
Series.rename、DataFrame.rename和DataFrame.rename_axis中存在错误,未将Series视为映射来重新标记 (GH 12623) -
在
.rolling.min和.rolling.max中进行清理以增强 dtype 处理 (GH 12373) -
在
groupby中存在错误,复杂类型被强制转换为浮点数 (GH 12902) -
当其 dtype 为
category或 tz-awaredatetime时,Series.map存在错误,会引发TypeError(GH 12473) -
在某些测试比较中,32 位平台上存在错误 (GH 12972)
-
当从
RangeIndex构造中回退时,索引强制转换存在错误 (GH 12893) -
在窗口函数中改进了错误消息,当传递无效参数(例如浮点窗口)时 (GH 12669)
-
在对子类化的
DataFrame进行切片时存在错误,定义为返回子类化的Series可能返回普通的Series(GH 11559) -
在输入具有
name并且结果为DataFrame或MultiIndex的情况下,使用.str访问器方法可能会引发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) -
当输入数据包含 tz-aware datetime 和 timedelta 时,
pd.concat存在错误,会引发AttributeError(GH 12620) -
pd.concat中存在 bug,未正确处理空Series(GH 11082) -
当指定
width时,.plot.bar对齐存在 bug,其中width是int(GH 12979) -
当二进制运算符的参数为常数时,
fill_value中的 bug 被忽略 (GH 12723) -
当使用 bs4 flavor 并解析只有一个标题列的表格时,
pd.read_html()存在 bug (GH 9178) -
当
margins=True和dropna=True时,.pivot_table存在 bug,其中空值仍然会对边距计数有贡献 (GH 12577) -
当
dropna=False时,.pivot_table中存在 bug,表格索引/列名消失 (GH 12133) -
当
margins=True和dropna=False时,pd.crosstab()中存在 bug,会引发异常 (GH 12642) -
当
name属性可以是可哈希类型时,Series.name存在 bug (GH 12610) -
.describe()中存在 bug,重置了分类列信息 (GH 11558) -
当在时间序列上调用
resample().count()时,loffset参数未被应用的 bug (GH 12725) -
pd.read_excel()现在接受与关键字参数names关联的列名 (GH 12870) -
当
Index作为参数时,pd.to_numeric()存在 bug,返回np.ndarray而不是Index(GH 12777) -
当类似日期时间的对象作为参数时,
pd.to_numeric()中存在 bug,可能引发TypeError(GH 12777) -
pd.to_numeric()存在 bug,使用标量会引发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 +
版本 0.18.0(2016 年 3 月 13 日)
这是从 0.17.1 版本开始的重大更新,包括少量的 API 更改、几个新功能、增强功能和性能改进,以及大量的 bug 修复。我们建议所有用户升级到此版本。
警告
pandas >= 0.18.0 不再支持与 Python 版本 2.6 和 3.3 的兼容性 (GH 7718,GH 11273)
警告
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 更改。
-
pd.test()顶级 nose 测试运行器可用 (GH 4327)。
在更新之前,请检查 API 更改 和 弃用。
v0.18.0 中的新内容
-
新功能
-
窗口函数现在是方法
-
重命名的更改
-
范围索引
-
str.extract 的更改
-
添加 str.extractall
-
str.cat 的更改
-
日期时间般的四舍五入
-
FloatIndex 中整数的格式化
-
dtype 分配行为的更改
-
to_xarray 方法
-
LaTeX 表示
-
pd.read_sas()的更改 -
其他增强
-
-
向后不兼容的 API 更改
-
NaT 和 Timedelta 操作
-
msgpack 的更改
-
.rank 的签名更改
-
QuarterBegin with n=0 中的错误
-
重新采样 API
-
降采样
-
上采样
-
以前的 API 将工作,但会有弃用警告
-
-
eval 的更改
-
其他 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]
``` ### 重命名的更改
`Series.rename` 和 `NDFrame.rename_axis` 现在可以接受标量或类似列表的参数,以修改 Series 或轴的 *名称*,除了它们以前的修改标签的行为。 ([GH 9494](https://github.com/pandas-dev/pandas/issues/9494), [GH 11965](https://github.com/pandas-dev/pandas/issues/11965))
```py
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]
新功能在方法链中运行良好。以前这些方法只接受函数或将 标签 映射到新标签的字典。对于函数或类似字典的值,这仍然像以前一样工作。 ### 范围索引
为了支持常见用例的内存节省替代方案,已将 Int64Index 子类添加了一个 RangeIndex。这与 Python range 对象(在 Python 2 中为 xrange)的实现类似,仅存储索引的起始、停止和步长值。它将与用户 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](https://github.com/pandas-dev/pandas/issues/11386))。
在 v0.18.0 中,向`extract`添加了`expand`参数。
+ `expand=False`:根据主题和正则表达式模式返回`Series`、`Index`或`DataFrame`,与 0.18.0 之前的行为相同。
+ `expand=True`:它始终返回一个`DataFrame`,从用户的角度来看更一致、更少令人困惑。
目前默认值是`expand=None`,会引发`FutureWarning`,并使用`expand=False`。为避免此警告,请明确指定`expand`。
```py
In [1]: pd.Series(['a1', 'b2', 'c3']).str.extract(r'ab', 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', 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', expand=True)
Out[17]:
0
0 1
1 2
2 NaN
[3 rows x 1 columns]
用正则表达式调用Index,如果有正好一个捕获组,设置expand=False会返回一个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]
用正则表达式调用Index,如果有多个捕获组,设置expand=False会引发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](https://github.com/pandas-dev/pandas/issues/11435))。
添加了一个新的友好的`ValueError`,以防止将`sep`作为参数而不是关键字参数的错误。([GH 11334](https://github.com/pandas-dev/pandas/issues/11334))。
```py
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?
``` ### 日期时间般的四舍五入
`DatetimeIndex`、`Timestamp`、`TimedeltaIndex`、`Timedelta`获得了用于日期时间般的四舍五入、向下取整和向上取整的`.round()`、`.floor()`和`.ceil()`方法。([GH 4314](https://github.com/pandas-dev/pandas/issues/4314), [GH 11963](https://github.com/pandas-dev/pandas/issues/11963))
朴素日期时间
```py
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')
Tz-aware 在本地时间中四舍五入、向下取整和向上取整
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)
时间增量
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.0 (GH 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 将设置为浮点数而不是整数。
以前的行为:
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() 方法,以将其转换为具有 pandas-like 接口的 xarray 对象,该接口适用于 > 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 笔记本中使用 nbconvert 转换为 latex。(GH 11778)
请注意,必须通过设置选项 pd.display.latex.repr=True 来激活此功能。(GH 12182)
例如,如果你有一个要使用 nbconvert 转换为 latex 的 jupyter 笔记本,请在第一个单元格中放置语句 pd.display.latex.repr=True,以便将包含的 DataFrame 输出也存储为 latex。
选项 display.latex.escape 和 display.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.quantile和Series.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)返回空框架,而不是self。(GH 11937) -
Series.head(0)和Series.tail(0)返回空序列,而不是self。(GH 11937) -
to_msgpack和read_msgpack的编码现在默认为'utf-8'。(GH 12170) -
文本文件解析函数(
.read_csv()、.read_table()、.read_fwf())的关键字参数顺序已更改以分组相关参数。(GH 11555) -
NaTType.isoformat现在返回字符串'NaT,以允许结果传递给Timestamp的构造函数。 (GH 12300)
NaT 和 Timedelta 的操作
NaT 和 Timedelta 具有扩展的算术运算,适用于 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'
但是,当包装在 dtype 为 datetime64[ns] 或 timedelta64[ns] 的 Series 中时,将尊重 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')
通过 Timedelta 在 Series 中减去 Timestamp 是有效的 (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 中引入的 to_msgpack 和 read_msgpack 中的错误,在 0.18.0 中得到修复,导致 Python 2 打包的文件无法被 Python 3 读取 (GH 12142)。以下表格描述了 msgpack 的向后和向前兼容性。
警告
| 打包于 | 可以解包于 |
|---|---|
| pre-0.17 / Python 2 | 任何 |
| pre-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 中解包。
.rank 的签名更改
Series.rank 和 DataFrame.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 偏移的行为取决于 n 参数为 0 时的日期是不一致的。 (GH 11406)
对于 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 偏移量,如果日期与季度开始日期在同一个月,则日期会向后滚动。
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 中已更正此行为,与 MonthBegin 和 YearBegin 等其他锚定偏移一致。
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')
重采样 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(...) 的 2 阶段操作,从而产生一个 Resampler。
In [82]: r = df.resample('2s')
In [83]: r
Out[83]: <pandas.core.resample.DatetimeIndexResampler object at 0x7ff230e71c30>
下采样
然后,您可以使用此对象执行操作。这些是下采样操作 (从较高频率到较低频率)。
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]
此外,现在重采样还支持 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]
上采样
上采样操作将频率从较低的转换为较高的。现在使用 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 将继续工作,但会有弃用警告
警告
这种重采样的新 API 包括一些内部更改,以与 0.18.0 之前的 API 兼容,大多数情况下都会出现弃用警告,因为重采样操作返回了一个延迟对象。我们可以截获操作并像 (pre 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 无法执行所有操作。这段代码意在对数据进行 2s 重采样,然后取 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
query 方法还添加了 inplace 关键字参数。
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]
警告
请注意,在 query 中 inplace 的默认值为 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_time和Series.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) -
当尝试与不是
DataFrame或其子类的对象进行合并时,pandas.merge()和DataFrame.merge()将显示特定的错误消息 (GH 12081) -
DataFrame.unstack和Series.unstack现在接受fill_value关键字,以允许在解除堆叠导致结果DataFrame中出现缺失值时直接替换缺失值。另一个好处是,指定fill_value将保留原始堆叠数据的数据类型。 (GH 9746) -
作为 窗口函数 和 重采样 的新 API 的一部分,聚合函数已经得到澄清,在无效的聚合上提供更具信息性的错误消息。 (GH 9052)。在 groupby 中提供了一整套示例。
-
NDFrame对象的统计函数(如sum(), mean(), min())现在会在传递给**kwargs的非 numpy 兼容参数时引发错误。 (GH 12301) -
.to_latex和.to_html增加了一个decimal参数,类似于.to_csv;默认值为'.'(GH 12031) -
构造带有空数据但具有索引的
DataFrame时,显示更有帮助的错误消息(GH 8020) -
.describe()现在将正确处理布尔类型作为分类类型(GH 6625) -
使用自定义输入时,
.transform出现无效时,错误消息更具帮助性(GH 10165) -
现在,指数加权函数允许直接指定 alpha(GH 10789),并且如果参数违反
0 < alpha <= 1,则会引发ValueError(GH 12492) ### 弃用 -
函数
pd.rolling_*、pd.expanding_*和pd.ewm*已弃用,并由相应的方法调用替换。请注意,新建议的语法包括所有参数(即使是默认值)(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(新)函数的freq和how参数已弃用,并将在将来的版本中移除。您可以在创建窗口函数之前简单地重新采样输入。(GH 11603)。例如,不再使用
s.rolling(window=5,freq='D').max()来获取滚动 5 天窗口的最大值,可以使用s.resample('D').mean().rolling(window=5).max(),它首先将数据重新采样为每日数据,然后提供一个滚动 5 天的窗口。 -
pd.tseries.frequencies.get_offset_name函数已弃用。使用偏移的.freqstr属性作为替代(GH 11192) -
pandas.stats.fama_macbeth例程已弃用,并将在将来的版本中移除(GH 6077) -
pandas.stats.ols、pandas.stats.plm和pandas.stats.var例程已弃用,并将在将来的版本中移除(GH 6077) -
在
HDFStore.select中使用长时间弃用的语法时,显示一个FutureWarning而不是一个DeprecationWarning,其中where子句不是字符串类似的(GH 12027) -
pandas.options.display.mpl_style配置已弃用,并将在将来的版本中移除 pandas。此功能更好地由 matplotlib 的样式表处理(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'>
其他索引器将对获取和设置都强制转换为相似的整数。 对于.loc、.ix和[],FutureWarning已被删除。
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和浮点索引器进行位置设置将将此值添加到索引中,而不是先前根据位置设置值。
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=True)`替代`rolling_corr_pairwise`([GH 4950](https://github.com/pandas-dev/pandas/issues/4950))
+ 改用`.expanding().corr(pairwise=True)`替代`expanding_corr_pairwise`([GH 4950](https://github.com/pandas-dev/pandas/issues/4950))
+ 删除了`DataMatrix`模块。 这在任何情况下都没有被导入到 pandas 命名空间中([GH 12111](https://github.com/pandas-dev/pandas/issues/12111))
+ 删除了`DataFrame.duplicated()`和`DataFrame.drop_duplicates()`中的`cols`关键字,而使用`subset`([GH 6680](https://github.com/pandas-dev/pandas/issues/6680))
+ 在`pd.io.sql`命名空间中,删除了自 0.14.0 起被弃用的`read_frame`和`frame_query`(均为`pd.read_sql`的别名)以及`write_frame`(`to_sql`的别名)函数([GH 6292](https://github.com/pandas-dev/pandas/issues/6292))。
+ 从`.factorize()`中删除了`order`关键字([GH 6930](https://github.com/pandas-dev/pandas/issues/6930)) ## 性能改进
+ 改进了`andrews_curves`的性能([GH 11534](https://github.com/pandas-dev/pandas/issues/11534))
+ 改进了大型`DatetimeIndex`、`PeriodIndex`和`TimedeltaIndex`的操作性能,包括`NaT`([GH 10277](https://github.com/pandas-dev/pandas/issues/10277))
+ 改进了`pandas.concat`的性能([GH 11958](https://github.com/pandas-dev/pandas/issues/11958))
+ 改进了`StataReader`的性能([GH 11591](https://github.com/pandas-dev/pandas/issues/11591))
+ 改进了包含`NaT`的日期时间的`Series`构造`Categoricals`的性能([GH 12077](https://github.com/pandas-dev/pandas/issues/12077))
+ 改进了没有分隔符的 ISO 8601 日期解析的性能([GH 11899](https://github.com/pandas-dev/pandas/issues/11899)),在时间戳之前有前导零([GH 11871](https://github.com/pandas-dev/pandas/issues/11871))以及具有空白区域的时区([GH 9714](https://github.com/pandas-dev/pandas/issues/9714)) ## Bug 修复
+ 当数据框为空时,`GroupBy.size`中存在错误。 ([GH 11699](https://github.com/pandas-dev/pandas/issues/11699))
+ 在请求多个时间段的`Period.end_time`中存在错误([GH 11738](https://github.com/pandas-dev/pandas/issues/11738))
+ 在具有时区感知日期时间的`.clip`中存在回归([GH 11838](https://github.com/pandas-dev/pandas/issues/11838))
+ 当边界落在频率上时,`date_range`存在错误([GH 11804](https://github.com/pandas-dev/pandas/issues/11804),[GH 12409](https://github.com/pandas-dev/pandas/issues/12409))
+ 将嵌套字典传递给`.groupby(...).agg(...)`时存在一致性错误([GH 9052](https://github.com/pandas-dev/pandas/issues/9052))
+ 接受`Timedelta`构造函数中的 Unicode([GH 11995](https://github.com/pandas-dev/pandas/issues/11995))
+ 在逐步读取时,对`StataReader`的值标签读取存在错误([GH 12014](https://github.com/pandas-dev/pandas/issues/12014))
+ 当`n`参数为`0`时,向量化`DateOffset`存在错误([GH 11370](https://github.com/pandas-dev/pandas/issues/11370))
+ 关于 numpy 1.11 的兼容性,涉及到`NaT`比较的更改([GH 12049](https://github.com/pandas-dev/pandas/issues/12049))
+ 在线程中从`StringIO`读取时,`read_csv`存在错误([GH 11790](https://github.com/pandas-dev/pandas/issues/11790))
+ 在对 datetimelikes 进行因子化且使用`Categoricals`时,未将`NaT`视为缺失值时存在错误([GH 12077](https://github.com/pandas-dev/pandas/issues/12077))
+ 当`Series`的值带有时区时,getitem 存在错误([GH 12089](https://github.com/pandas-dev/pandas/issues/12089))
+ 当其中一个变量为'name'时,`Series.str.get_dummies`存在错误([GH 12180](https://github.com/pandas-dev/pandas/issues/12180))
+ 在连接时,`pd.concat`存在错误,同时连接带有时区的 NaT 系列。([GH 11693](https://github.com/pandas-dev/pandas/issues/11693),[GH 11755](https://github.com/pandas-dev/pandas/issues/11755),[GH 12217](https://github.com/pandas-dev/pandas/issues/12217))
+ 在版本<= 108 文件中使用`pd.read_stata`存在错误([GH 12232](https://github.com/pandas-dev/pandas/issues/12232))
+ 当索引为`DatetimeIndex`且包含非零纳秒部分时,使用`Nano`频率进行`Series.resample`存在错误([GH 12037](https://github.com/pandas-dev/pandas/issues/12037))
+ 在稀疏索引中使用`.nunique`进行重新采样存在错误([GH 12352](https://github.com/pandas-dev/pandas/issues/12352))
+ 删除了一些编译器警告([GH 12471](https://github.com/pandas-dev/pandas/issues/12471))
+ 解决了 python 3.5 中`boto`的兼容问题([GH 11915](https://github.com/pandas-dev/pandas/issues/11915))
+ 在带有时区的`Timestamp`或`DatetimeIndex`中减去`NaT`时存在错误([GH 11718](https://github.com/pandas-dev/pandas/issues/11718))
+ 在单个带时区的`Timestamp`的`Series`减法中存在错误([GH 12290](https://github.com/pandas-dev/pandas/issues/12290))
+ 在 PY2 中使用兼容迭代器来支持`.next()`([GH 12299](https://github.com/pandas-dev/pandas/issues/12299))
+ 对负值进行`Timedelta.round`时的错误([GH 11690](https://github.com/pandas-dev/pandas/issues/11690))
+ 在`CategoricalIndex`上针对`.loc`可能导致普通`Index`的错误([GH 11586](https://github.com/pandas-dev/pandas/issues/11586))
+ 当存在重复列名时,`DataFrame.info`存在错误([GH 11761](https://github.com/pandas-dev/pandas/issues/11761))
+ 在具有时区感知对象的`.copy`中存在的错误([GH 11794](https://github.com/pandas-dev/pandas/issues/11794))
+ `Series.apply`和`Series.map`中存在的错误,`timedelta64`未被包装([GH 11349](https://github.com/pandas-dev/pandas/issues/11349))
+ `DataFrame.set_index()`中存在的错误,带有 tz-aware `Series`([GH 12358](https://github.com/pandas-dev/pandas/issues/12358))
+ `DataFrame`的子类中存��的错误,`AttributeError`未传播([GH 11808](https://github.com/pandas-dev/pandas/issues/11808))
+ 在 tz-aware 数据上进行 groupby 时,选择不返回`Timestamp`的错误([GH 11616](https://github.com/pandas-dev/pandas/issues/11616))
+ `pd.read_clipboard`和`pd.to_clipboard`函数中存在不支持 Unicode 的错误;升级包括`pyperclip`到 v1.5.15([GH 9263](https://github.com/pandas-dev/pandas/issues/9263))
+ 包含赋值的`DataFrame.query`中存在的错误([GH 8664](https://github.com/pandas-dev/pandas/issues/8664))
+ 在`from_msgpack`中存在的错误,如果`DataFrame`具有对象列,则解压缩的`DataFrame`的列的`__contains__()`失败。 ([GH 11880](https://github.com/pandas-dev/pandas/issues/11880))
+ 在具有`TimedeltaIndex`的分类数据上进行`.resample`时存在的错误([GH 12169](https://github.com/pandas-dev/pandas/issues/12169))
+ 在将标量日期时间广播到`DataFrame`时,时区信息丢失的错误([GH 11682](https://github.com/pandas-dev/pandas/issues/11682))
+ 从带有混合 tz 的`Timestamp`创建`Index`时,强制转换为 UTC 的错误([GH 11488](https://github.com/pandas-dev/pandas/issues/11488))
+ `to_numeric`中存在的错误,如果输入超过一个维度,则不会引发错误([GH 11776](https://github.com/pandas-dev/pandas/issues/11776))
+ 解析具有非零分钟的时区偏移字符串时存在的错误([GH 11708](https://github.com/pandas-dev/pandas/issues/11708))
+ 在 matplotlib 1.5+下,`df.plot`中的错误导致条形图使用不正确的颜色([GH 11614](https://github.com/pandas-dev/pandas/issues/11614))
+ 使用关键字参数时,`groupby` `plot`方法中存在错误([GH 11805](https://github.com/pandas-dev/pandas/issues/11805))。
+ 在设置`keep=False`时,`DataFrame.duplicated`和`drop_duplicates`中存在错误导致虚假匹配([GH 11864](https://github.com/pandas-dev/pandas/issues/11864))
+ 具有重复键的`.loc`结果可能具有不正确 dtype 的`Index`([GH 11497](https://github.com/pandas-dev/pandas/issues/11497))
+ `pd.rolling_median`中存在的错误,即使内存充足也会导致内存分配失败([GH 11696](https://github.com/pandas-dev/pandas/issues/11696))
+ `DataFrame.style`中存在虚假零值的错误([GH 12134](https://github.com/pandas-dev/pandas/issues/12134))
+ `DataFrame.style`中存在的错误,整数列不从 0 开始([GH 12125](https://github.com/pandas-dev/pandas/issues/12125))
+ `.style.bar`中的错误可能在特定浏览器中无法正确渲染([GH 11678](https://github.com/pandas-dev/pandas/issues/11678))
+ `Timedelta` 类型与 `numpy.array` 中的 `Timedelta` 进行丰富比较时出现无限递归的错误([GH 11835](https://github.com/pandas-dev/pandas/issues/11835))
+ `DataFrame.round` 函数存在删除列索引名称的错误([GH 11986](https://github.com/pandas-dev/pandas/issues/11986))
+ 在替换混合类型 `Dataframe` 中的值时,`df.replace` 函数存在错误([GH 11698](https://github.com/pandas-dev/pandas/issues/11698))
+ 当没有提供新名称时,`Index` 类的复制名称存在错误([GH 11193](https://github.com/pandas-dev/pandas/issues/11193))
+ `read_excel` 函数在存在空表且 `sheetname=None` 时无法读取任何非空表的错误([GH 11711](https://github.com/pandas-dev/pandas/issues/11711))
+ `read_excel` 函数在提供 `parse_dates` 和 `date_parser` 关键字时未能引发 `NotImplemented` 错误([GH 11544](https://github.com/pandas-dev/pandas/issues/11544))
+ `pymysql` 连接中 `read_sql` 函数存在错误,无法返回分块数据([GH 11522](https://github.com/pandas-dev/pandas/issues/11522))
+ `.to_csv` 函数忽略浮点索引的格式化参数 `decimal`、`na_rep`、`float_format` 的错误([GH 11553](https://github.com/pandas-dev/pandas/issues/11553))
+ `Int64Index` 和 `Float64Index` 函数中无法使用取模运算符的错误([GH 9244](https://github.com/pandas-dev/pandas/issues/9244))
+ `MultiIndex.drop` 函数对未按词典顺序排列的多级索引存在错误([GH 12078](https://github.com/pandas-dev/pandas/issues/12078))
+ 当遮蔽一个空的 `DataFrame` 时出现错误([GH 11859](https://github.com/pandas-dev/pandas/issues/11859))
+ 当列数与提供的系列数不匹配时,`.plot` 函数可能修改 `colors` 输入的错误([GH 12039](https://github.com/pandas-dev/pandas/issues/12039))
+ 当索引具有 `CustomBusinessDay` 频率时,`Series.plot` 函数无法绘制的错误([GH 7222](https://github.com/pandas-dev/pandas/issues/7222))
+ 使用 sqlite 回退时,`.to_sql` 函数存在 `datetime.time` 值的错误([GH 8341](https://github.com/pandas-dev/pandas/issues/8341))
+ `read_excel` 函数在 `squeeze=True` 时无法读取只有一列数据的错误([GH 12157](https://github.com/pandas-dev/pandas/issues/12157))
+ `read_excel` 函数存在无法读取一个空列的错误([GH 12292](https://github.com/pandas-dev/pandas/issues/12292),[GH 9002](https://github.com/pandas-dev/pandas/issues/9002))
+ `.groupby` 函数在数据框中只有一行时,如果列名错误未引发 `KeyError` 的错误([GH 11741](https://github.com/pandas-dev/pandas/issues/11741))
+ 在指定空数据上指定 dtype 时,`.read_csv` 函数产生错误的错误([GH 12048](https://github.com/pandas-dev/pandas/issues/12048))
+ `.read_csv` 函数将字符串如 `'2E'` 视为有效浮点数的错误([GH 12237](https://github.com/pandas-dev/pandas/issues/12237))
+ 使用调试符号构建 *pandas* 出现错误([GH 12123](https://github.com/pandas-dev/pandas/issues/12123))
+ 移除了`DatetimeIndex`的`millisecond`属性。这将始终引发`ValueError` ([GH 12019](https://github.com/pandas-dev/pandas/issues/12019)).
+ 在具有只读数据的`Series`构造函数中出现的错误 ([GH 11502](https://github.com/pandas-dev/pandas/issues/11502))
+ 移除了`pandas._testing.choice()`。应该使用`np.random.choice()`代替。 ([GH 12386](https://github.com/pandas-dev/pandas/issues/12386))
+ 在`.loc` setitem 索引器中阻止使用 TZ-aware DatetimeIndex 的错误 ([GH 12050](https://github.com/pandas-dev/pandas/issues/12050))
+ 在`.style`中索引和 MultiIndexes 未显示的错误 ([GH 11655](https://github.com/pandas-dev/pandas/issues/11655))
+ 在`to_msgpack`和`from_msgpack`中,未正确序列化或反序列化`NaT`的错误 ([GH 12307](https://github.com/pandas-dev/pandas/issues/12307)).
+ 由于高度相似值的四舍五入误差,导致`.skew`和`.kurt`中的错误 ([GH 11974](https://github.com/pandas-dev/pandas/issues/11974))
+ 在`Timestamp`构造函数中,如果 HHMMSS 没有用‘:’分隔,微秒分辨率会丢失的错误 ([GH 10041](https://github.com/pandas-dev/pandas/issues/10041))
+ 在`buffer_rd_bytes`中,如果读取失败,src->buffer 可能会被释放多次,导致段错误的错误 ([GH 12098](https://github.com/pandas-dev/pandas/issues/12098))
+ 在`crosstab`中,具有不重叠索引的参数会返回`KeyError`的错误 ([GH 10291](https://github.com/pandas-dev/pandas/issues/10291))
+ 在`DataFrame.apply`中,如果`dtype`不是 numpy dtype,则未阻止缩减的错误 ([GH 12244](https://github.com/pandas-dev/pandas/issues/12244))
+ 初始化分类系列时出现的错误。([GH 12336](https://github.com/pandas-dev/pandas/issues/12336))
+ 在`.to_datetime`中通过设置`utc=True`指定 UTC `DatetimeIndex`时出现的错误 ([GH 11934](https://github.com/pandas-dev/pandas/issues/11934))
+ 在`read_csv`中增加 CSV 读取器缓冲区大小时出现的错误 ([GH 12494](https://github.com/pandas-dev/pandas/issues/12494))
+ 在设置具有重复列名的`DataFrame`的列时出现的错误 ([GH 12344](https://github.com/pandas-dev/pandas/issues/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 + ## 新功能
### 窗口函数现在是方法
窗口函数已重构为`Series/DataFrame`对象的方法,而不是顶层函数,后者现已弃用。这允许这些窗口类型函数具有与`.groupby`相似的 API。请参阅完整文档此处 ([GH 11603](https://github.com/pandas-dev/pandas/issues/11603), [GH 12373](https://github.com/pandas-dev/pandas/issues/12373))
```py
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]
``` ### 更改名称
`Series.rename`和`NDFrame.rename_axis`现在可以接受标量或类似列表的参数来更改 Series 或轴的*名称*,以及它们以前的更改标签的行为。([GH 9494](https://github.com/pandas-dev/pandas/issues/9494), [GH 11965](https://github.com/pandas-dev/pandas/issues/11965))
```py
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]
新功能现在在方法链中运行良好。以前,这些方法只接受将标签映射到新标签的函数或字典。对于函数或类似字典的值,这将继续像以前一样工作。 ### 范围索引
已将RangeIndex添加到Int64Index子类中,以支持常见用例的节省内存替代方法。这与 python range对象(在 python 2 中为xrange)有相似的实现,它只存储索引的开始、停止和步长值。它将与用户 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](https://github.com/pandas-dev/pandas/issues/11386))。
在 v0.18.0 中,添加了 `extract` 的 `expand` 参数。
+ `expand=False`:它根据主题和正则表达式模式的不同,返回一个 `Series`、`Index` 或 `DataFrame`(与 v0.18.0 之前的行为相同)。
+ `expand=True`:它始终返回一个 `DataFrame`,从用户的角度来看更一致且更少令人困惑。
目前默认为 `expand=None`,会产生 `FutureWarning`,并使用 `expand=False`。为避免此警告,请明确指定 `expand`。
```py
In [1]: pd.Series(['a1', 'b2', 'c3']).str.extract(r'ab', 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', 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', expand=True)
Out[17]:
0
0 1
1 2
2 NaN
[3 rows x 1 columns]
使用具有正好一个捕获组的正则表达式调用 Index 时,如果 expand=False,则返回一个 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]
使用具有多个捕获组的正则表达式调用 Index 时,如果 expand=False,则会引发 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](https://github.com/pandas-dev/pandas/issues/11435))。
添加了一个新的、更友好的 `ValueError`,以防止将 `sep` 错误地作为参数而不是关键字参数传递。([GH 11334](https://github.com/pandas-dev/pandas/issues/11334))。
```py
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?
``` ### 日期时间舍入
`DatetimeIndex`、`Timestamp`、`TimedeltaIndex`、`Timedelta` 现在具有用于日期时间舍入、向下取整和向上取整的 `.round()`、`.floor()` 和 `.ceil()` 方法。([GH 4314](https://github.com/pandas-dev/pandas/issues/4314), [GH 11963](https://github.com/pandas-dev/pandas/issues/11963))
朴素日期时间
```py
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)
时间增量
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.0 (GH 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 将设置为浮点数而不是整数。
之前的行为:
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 笔记本中使用 nbconvert 转换为 LaTeX。(GH 11778)
请注意,必须通过设置选项 pd.display.latex.repr=True 来激活此功能(GH 12182)
例如,如果您有一个 Jupyter 笔记本,计划使用 nbconvert 转换为 LaTeX,将语句 pd.display.latex.repr=True 放在第一个单元格中,以便将包含的 DataFrame 输出也存储为 LaTeX。
选项 display.latex.escape 和 display.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.quantile和Series.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)。更多详情请参见 here -
HDFStore现在是可迭代的:for k in store等效于for k in store.keys()(GH 12221). -
为
.dt添加了缺失的方法/字段,用于Period(GH 8848) -
整个代码库已经符合
PEP规范化 (GH 12096) ### 窗口函数现在是方法
窗口函数已经重构为 Series/DataFrame 对象上的方法,而不是顶层函数,现在已经弃用。这使得这些窗口类型函数具有了与 .groupby 类似的 API。查看完整文档 here (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]
具有可用方法和属性的选项卡完成。
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]
重命名更改
Series.rename 和 NDFrame.rename_axis 现在可以接受标量或类似列表的参数来修改 Series 或轴的 名称,除了它们以前修改标签的行为。 (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]
新功能在方法链中运行良好。以前,这些方法只接受将标签映射到新标签的函数或字典。对于函数或类似字典的值,这仍然像以前一样工作。
范围索引
RangeIndex已添加到Int64Index子类中,以支持常见用例的节省内存的替代方案。这与 python 的range对象(在 python 2 中为xrange)具有类似的实现,因为它仅存储索引的起始、停止和步长值。如果需要,它将与用户 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 中,添加了expand参数到extract。
-
expand=False:根据主题和正则表达式模式,返回一个Series、Index或DataFrame(与 0.18.0 之前的行为相同)。 -
expand=True:它始终返回一个DataFrame,这对用户来说更一致,更少令人困惑。
目前默认值为expand=None,会产生FutureWarning并使用expand=False。为避免此警告,请明确指定expand。
In [1]: pd.Series(['a1', 'b2', 'c3']).str.extract(r'ab', 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', 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', expand=True)
Out[17]:
0
0 1
1 2
2 NaN
[3 rows x 1 columns]
对具有正好一个捕获组的正则表达式的Index调用,如果expand=False,则返回一个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]
对具有多个捕获组的正则表达式的Index调用,如果expand=False,则引发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?
日期时间四舍五入
DatetimeIndex、Timestamp、TimedeltaIndex、Timedelta已经获得了.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)
时间增量
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.0 (GH 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 将设置为浮点数而不是整数。
以前的行为:
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 笔记本中使用 nbconvert 转换为 latex。(GH 11778)
请注意,这必须通过设置选项pd.display.latex.repr=True来激活。(GH 12182)
例如,如果您有一个 jupyter 笔记本,计划使用 nbconvert 转换为 latex,请在第一个单元格中放置语句pd.display.latex.repr=True,以便包含的 DataFrame 输出也存储为 latex。
选项 display.latex.escape 和 display.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.quantile和Series.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)返回空框架,而不是self。 (GH 11937) -
Series.head(0)和Series.tail(0)返回空系列,而不是self。 (GH 11937) -
to_msgpack和read_msgpack的编码现在默认为'utf-8'。 (GH 12170) -
文本文件解析函数的关键字参数顺序 (
.read_csv(),.read_table(),.read_fwf()) 已更改为分组相关参数。 (GH 11555) -
NaTType.isoformat现在返回字符串'NaT',以允许结果传递给Timestamp的构造函数。 (GH 12300)
NaT 和 Timedelta 操作
NaT 和 Timedelta 有了更多的算术操作,适用于 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'
但是,当包装在 dtype 为 datetime64[ns] 或 timedelta64[ns] 的 Series 中时,将尊重 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 中通过 Timedelta 减去 Timestamp 的操作有效 (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 中引入的 to_msgpack 和 read_msgpack 中的错误在 0.18.0 中已修复,导致 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 中解包。
.rank的签名更改
Series.rank和DataFrame.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]
当 n=0 时,QuarterBegin中的错误
在之前的版本中,如果日期在n参数为 0 时,QuarterBegin偏移量的行为是不一致的。 (GH 11406)
对于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偏移量,如果日期与季度开始日期在同一个月,则日期将被向后滚动。
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 中得到了纠正,与其他锚定偏移量(如MonthBegin和YearBegin)保持一致。
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')
重新采样 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:
现在,你可以像.groupby(...)一样将.resample(..)写成一个两阶段的操作,产生一个Resampler。
In [82]: r = df.resample('2s')
In [83]: r
Out[83]: <pandas.core.resample.DatetimeIndexResampler object at 0x7ff230e71c30>
下采样
你可以使用这个对象来执行操作。这些是下采样操作(从更高的频率到更低的频率)。
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]
上采样
上采样操作将你从较低的频率带到较高的频率。现在,这些是通过带有backfill()、ffill()、fillna()和asfreq()方法的Resampler对象执行的。
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,在大多数情况下会返回一个延迟对象的弃用警告。我们可以拦截操作并执行 (pre 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]
警告
请注意,在 query 中 inplace 的默认值为 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_time和Series.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 中使用非 ASCII 编码(例如utf-8)的参数encoding([GH 7061](https://github.com/pandas-dev/pandas/issues/7061)) -
pandas.merge()和DataFrame.merge()在尝试与不是DataFrame或其子类的对象合并时将显示特定错误消息 (GH 12081) -
DataFrame.unstack和Series.unstack现在接受fill_value关键字,以允许在展开结果中出现缺失值时直接替换缺失值。另一个好处是,指定fill_value将保留原始堆叠数据的数据类型。 (GH 9746) -
作为窗口函数和重新采样的新 API 的一部分,聚合函数已经得到澄清,在无效的聚合上提供更具信息性的错误消息。 (GH 9052). 在 groupby 中提供了一整套示例。
-
NDFrame对象的统计函数(如sum(), mean(), min())现在会在传递非兼容的参数给**kwargs时引发错误 (GH 12301) -
.to_latex和.to_html现在增加了一个decimal参数,类似于.to_csv;默认值为'.'(GH 12031) -
在使用空数据但具有索引构建
DataFrame时提供更有帮助的错误消息 (GH 8020) -
.describe()现在将正确处理布尔类型作为分类变量 (GH 6625) -
在使用用户定义输入时,无效的
.transform现在会提供更有帮助的错误消息 (GH 10165) -
指数加权函数现在允许直接指定 alpha (GH 10789),并且如果参数违反
0 < alpha <= 1,将引发ValueError(GH 12492) ### 弃用功能 -
函数
pd.rolling_*,pd.expanding_*, 和pd.ewm*已被弃用,并由相应的方法调用替代。请注意,新建议的语法包括所有参数(即使是默认值) (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(新)函数的freq和how参数已被弃用,并将在将来的版本中移除。您可以在创建窗口函数之前简单地对输入进行重新采样。 (GH 11603).例如,不再使用
s.rolling(window=5,freq='D').max()来获取滚动 5 天窗口上的最大值,可以使用s.resample('D').mean().rolling(window=5).max(),首先将数据重新采样为每日数据,然后提供一个滚动 5 天窗口。 -
pd.tseries.frequencies.get_offset_name函数已被弃用。使用偏移量的.freqstr属性作为替代方案 (GH 11192) -
pandas.stats.fama_macbeth例程已被弃用,并将在将来的版本中移除 (GH 6077) -
pandas.stats.ols、pandas.stats.plm和pandas.stats.var程序已被弃用,并将在将来的版本中移除(GH 6077) -
在
HDFStore.select中,如果where子句不是类似字符串的形式,则显示FutureWarning,而不是DeprecationWarning,表示长时间弃用的语法(GH 12027) -
pandas.options.display.mpl_style配置已被弃用,并将在 pandas 的将来版本中移除。这个功能最好由 matplotlib 的样式表来处理(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'>
其他索引器将在获取和设置时强制转换为类似整数的值。对于 .loc、.ix 和 [],FutureWarning 已被移除。
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 和浮点索引器进行位置设置将向索引中添加此值,而不是以前按位置设置值。
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](https://github.com/pandas-dev/pandas/issues/4950))
+ 移除 `expanding_corr_pairwise`,改为使用 `.expanding().corr(pairwise=True)`([GH 4950](https://github.com/pandas-dev/pandas/issues/4950))
+ 移除 `DataMatrix` 模块。这在任何情况下都没有被导入到 pandas 命名空间中([GH 12111](https://github.com/pandas-dev/pandas/issues/12111))
+ 在 `DataFrame.duplicated()` 和 `DataFrame.drop_duplicates()` 中,`cols` 关键字已被弃用,改为使用 `subset`([GH 6680](https://github.com/pandas-dev/pandas/issues/6680))
+ 移除 `read_frame` 和 `frame_query`(都是 `pd.read_sql` 的别名)以及 `write_frame`(`to_sql` 的别名)函数在 `pd.io.sql` 命名空间中,自 0.14.0 版本起已被弃用([GH 6292](https://github.com/pandas-dev/pandas/issues/6292))。
+ 移除 `.factorize()` 中的 `order` 关键字([GH 6930](https://github.com/pandas-dev/pandas/issues/6930))
### NaT 和 Timedelta 操作
`NaT` 和 `Timedelta` 扩展了算术运算,适用于 `Series` 的算术运算也相应扩展。 对于 `datetime64[ns]` 或 `timedelta64[ns]` 定义的操作现在也适用于 `NaT` ([GH 11564](https://github.com/pandas-dev/pandas/issues/11564))。
现在 `NaT` 支持与整数和浮点数进行算术运算。
```py
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'
但是,当包装在 dtype 为 datetime64[ns] 或 timedelta64[ns] 的 Series 中时,将尊重 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')
通过 Timedelta 对 Series 中的 Timestamp 进行减法运算有效(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 中引入的 to_msgpack 和 read_msgpack 中的错误在 0.18.0 中修复,导致 Python 2 打包的文件无法被 Python 3 读取 (GH 12142)。 以下表格描述了 msgpack 的向后和向前兼容性。
警告
| 由以下版本打包 | 可以解包 |
|---|---|
| pre-0.17 / Python 2 | 任何 |
| pre-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 对于由较旧版本打包的文件是向后兼容的,但对于 0.17 在 Python 2 中打包的文件,只能在 Python 2 中解包。
.rank 的签名更改
Series.rank 和 DataFrame.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]
季度起始日当 n=0 时存在的错误
在先前版本中,当 n 参数为 0 时,QuarterBegin 偏移的行为取决于日期。
对于 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 偏移,如果日期与季度开始日期在同一个月,则日期会向后滚动。
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 中得到纠正,与其他锚定偏移量(如 MonthBegin 和 YearBegin)保持一致。
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')
重新采样 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:
现在,您可以像 .groupby(...) 一样将 .resample(..) 写成两阶段操作,这将产生一个 Resampler。
In [82]: r = df.resample('2s')
In [83]: r
Out[83]: <pandas.core.resample.DatetimeIndexResampler object at 0x7ff230e71c30>
降采样
然后,您可以使用此对象执行操作。这些是降采样操作(从更高频率到更低频率)。
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]
上采样
上采样操作将您从低频率转到高频率。现在,这些操作由 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 仍然可用,但已弃用。
警告
重新采样的这种新 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
降采样
然后,您可以使用此对象执行操作。这些是降采样操作(从更高频率到更低频率)。
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]
上采样
上采样操作将您从较低频率转移到较高频率。现在使用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 将继续工作,但会有弃用警告
警告
这个新的重采样 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]
警告
请注意,在query中inplace的默认值为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_time和Series.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()现在支持非 ascii 编码(例如utf-8)在 Python 2 中使用参数encoding(GH 7061) -
当尝试与不是
DataFrame或其子类的对象合并时,pandas.merge()和DataFrame.merge()将显示特定的错误消息(GH 12081) -
DataFrame.unstack和Series.unstack现在接受fill_value关键字,以允许在 unstack 导致结果DataFrame中出现缺失值时直接替换缺失值。另一个好处是,指定fill_value将保留原始堆叠数据的数据类型(GH 9746) -
作为窗口函数和重新采样的新 API 的一部分,聚合函数已经得到澄清,对无效聚合提出更具信息性的错误消息(GH 9052)。在 groupby 中提供了一整套示例。
-
NDFrame对象的统计函数(如sum(), mean(), min())现在会在传递给**kwargs的非 numpy 兼容参数时引发错误(GH 12301) -
.to_latex和.to_html现在增加了一个decimal参数,类似于.to_csv;默认值为'.'(GH 12031) -
当使用空数据但带有索引构建
DataFrame时,会提供更有帮助的错误消息(GH 8020) -
.describe()现在将正确处理 bool 类型作为分类变量(GH 6625) -
在使用用户定义输入的无效
.transform时提供更有帮助的错误消息(GH 10165) -
指数加权函数现在允许直接指定 alpha 值(GH 10789),并且如果参数违反
0 < alpha <= 1,则会引发ValueError(GH 12492)
弃用
-
函数
pd.rolling_*,pd.expanding_*和pd.ewm*已被弃用,并被相应的方法调用所取代。请注意,新建议的语法包括所有参数(即使是默认值)(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(新)函数的freq和how参数已被弃用,并将在将来的版本中移除。您可以在创建窗口函数之前简单地对输入进行重新采样(GH 11603)。例如,不再使用
s.rolling(window=5,freq='D').max()来获取滚动 5 天窗口上的最大值,而是可以使用s.resample('D').mean().rolling(window=5).max(),首先将数据重新采样为每日数据,然后提供一个滚动 5 天窗口。 -
pd.tseries.frequencies.get_offset_name函数已弃用。使用偏移的.freqstr属性作为替代方案 (GH 11192) -
pandas.stats.fama_macbeth例程已弃用,并将在未来版本中移除 (GH 6077) -
pandas.stats.ols、pandas.stats.plm和pandas.stats.var例程已弃用,并将在未来版本中移除 (GH 6077) -
在
HDFStore.select中,使用长时间弃用的语法时,将显示FutureWarning而不是DeprecationWarning,其中where子句不是类似字符串的情况 (GH 12027) -
pandas.options.display.mpl_style配置已弃用,并将在未来版本的 pandas 中移除。此功能最好由 matplotlib 的 样式表 处理 (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'>
其他索引器将在获取和设置时强制转换为类似整数。对于 .loc、.ix 和 [],FutureWarning 已被移除。
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 和浮点索引器进行位置设置将将此值添加到索引中,而不是以前按位置设置值。
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) -
弃用
cols关键字,改用DataFrame.duplicated()和DataFrame.drop_duplicates()中的subset(GH 6680) -
移除
read_frame和frame_query(均为pd.read_sql的别名)以及write_frame(to_sql的别名)函数在pd.io.sql命名空间中,自 0.14.0 版本起已弃用 (GH 6292)。 -
从
.factorize()中移除了order关键字(GH 6930)
性能改进
-
提高了
andrews_curves的性能(GH 11534) -
提高了巨大
DatetimeIndex、PeriodIndex和TimedeltaIndex的操作性能,包括NaT(GH 10277) -
提高了
pandas.concat的性能(GH 11958) -
提高了
StataReader的性能(GH 11591) -
在包含
NaT的日期时间Series的Categoricals构造中,提高了性能(GH 12077) -
提高了 ISO 8601 日期解析的性能,包括无分隔符的日期(GH 11899)、前导零(GH 11871)和时区前的空格(GH 9714)
错误修复
-
当数据框为空时,修复了
GroupBy.size中的错误(GH 11699) -
当请求时间段的倍数时,修复了
Period.end_time中的错误(GH 11738) -
在具有时区的日期时间上,修复了
.clip中的回归(GH 11838) -
在将嵌套字典传递给
.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) -
当因子化和使用
Categoricals时,未将NaT视为缺失值的错误(GH 12077) -
当
Series的值带有时区时,修复了 getitem 中的错误(GH 12089) -
修复了
Series.str.get_dummies中一个变量为‘name’时的错误(GH 12180) -
连接 tz-aware NaT series 时
pd.concat中存在的错误。 (GH 11693, GH 11755, GH 12217) -
pd.read_stata中存在版本 <= 108 文件的错误 (GH 12232) -
当索引是
DatetimeIndex并且包含非零纳秒部分时,使用Nano频率的Series.resample中存在的错误 (GH 12037) -
使用
.nunique和稀疏索引进行重采样的错误 (GH 12352) -
移除了一些编译器警告 (GH 12471)
-
在 python 3.5 中使用
boto的兼容性问题解决方案 (GH 11915) -
从具有时区的
Timestamp或DatetimeIndex减去NaT中存在的错误 (GH 11718) -
单个 tz-aware
Timestamp的Series减法中存在的错误 (GH 12290) -
使用兼容的迭代器在 PY2 中支持
.next()(GH 12299) -
Timedelta.round中存在负值的错误 (GH 11690) -
针对
CategoricalIndex的.loc中可能导致正常Index的错误 (GH 11586) -
当存在重复列名时
DataFrame.info中存在的错误 (GH 11761) -
日期时间 tz-aware 对象的
.copy中存在的错误 (GH 11794) -
在
Series.apply和Series.map中存在的timedelta64未包装的错误 (GH 11349) -
DataFrame.set_index()中存在带有时区感知的Series的错误 (GH 12358) -
DataFrame的子类中存在AttributeError未传播的错误 (GH 11808) -
在 tz-aware 数据上进行分组,选择未返回
Timestamp的错误 (GH 11616) -
pd.read_clipboard和pd.to_clipboard函数不支持 Unicode 的错误;升级包含了pyperclip到 v1.5.15 (GH 9263) -
包含赋值的
DataFrame.query中存在的错误 (GH 8664) -
在
from_msgpack中,如果DataFrame具有对象列,则对解压缩的DataFrame的列进行__contains__()失败的错误。 (GH 11880) -
在具有
TimedeltaIndex的分类数据上的.resample中存在的错误 (GH 12169) -
当将标量日期时间广播到
DataFrame时,时区信息丢失的 Bug(GH 11682) -
从具有混合时区的
Timestamp创建Index时的 Bug 会强制转换为 UTC(GH 11488) -
在
to_numeric中的 Bug 不会在输入为多维时引发异常(GH 11776) -
在解析具有非零分钟的时区偏移字符串时的 Bug(GH 11708)
-
在 matplotlib 1.5+ 下,
df.plot中的 Bug 会为柱状图使用不正确的颜色(GH 11614) -
在使用关键字参数时,
groupbyplot方法中的 Bug(GH 11805) -
在设置
keep=False时,DataFrame.duplicated和drop_duplicates中的 Bug 会导致错误匹配(GH 11864) -
在重复键具有的
.loc结果中,可能会出现具有不正确 dtype 的Index的 Bug(GH 11497) -
在
pd.rolling_median中的 Bug,即使内存充足,内存分配也失败了(GH 11696) -
在
DataFrame.style中的 Bug 会产生错误的零值(GH 12134) -
在
DataFrame.style中,整数列不从 0 开始的 Bug(GH 12125) -
使用特定浏览器时,
.style.bar中的 Bug 可能无法正确渲染(GH 11678) -
与
numpy.array中的Timedelta进行比较时,发生无限递归的Timedelta的 Bug (GH 11835) -
在
DataFrame.round中的 Bug 会丢失列索引名称(GH 11986) -
在混合数据类型
Dataframe中替换值时,df.replace中的 Bug 会导致问题(GH 11698) -
当未提供新名称时,
Index中的 Bug 会阻止复制传递的Index名称(GH 11193) -
read_excel中的 Bug 在存在空工作表且sheetname=None时无法读取任何非空工作表(GH 11711) -
当提供关键字
parse_dates和date_parser时,read_excel中的 Bug 未能引发NotImplemented错误(GH 11544) -
使用
pymysql连接时,read_sql中的 Bug 无法返回分块数据(GH 11522) -
在
.to_csv中,忽略了浮点索引的格式化参数decimal、na_rep、float_format的 Bug(GH 11553) -
Int64Index和Float64Index中的错误,阻止了模数运算符的使用(GH 9244) -
MultiIndex.drop中的错误,未按字典顺序排序 MultiIndexes(GH 12078) -
在掩盖空的
DataFrame时的DataFrame中的错误(GH 11859) -
当列数不匹配所提供的系列数量时,
.plot中可能会修改colors输入的错误(GH 12039)。 -
当索引具有
CustomBusinessDay频率时,Series.plot失败的错误(GH 7222)。 -
对于带有 sqlite 回退的
datetime.time值,to_sql中的错误(GH 8341) -
当
squeeze=True时,read_excel在只有一列数据时无法读取的错误(GH 12157) -
.groupby中的错误,如果 dataframe 中只有一行,则不会针对错误的列引发KeyError(GH 11741) -
在空数据上指定 dtype 的情况下,
.read_csv中出现错误(GH 12048) -
.read_csv中字符串如'2E'被视为有效浮点数的错误(GH 12237) -
在使用调试符号构建 pandas 时出现的错误(GH 12123)
-
移除了
DatetimeIndex的millisecond属性。这将始终引发ValueError(GH 12019)。 -
在只读数据中的
Series构造函数中的错误(GH 11502) -
移除了
pandas._testing.choice()。应该使用np.random.choice()代替。 (GH 12386) -
.locsetitem 索引器中的错误,阻止了使用 TZ-aware DatetimeIndex(GH 12050) -
.style中索引和 MultiIndexes 不出现的错误(GH 11655) -
to_msgpack和from_msgpack中未正确序列化或反序列化NaT的错误(GH 12307) -
由于高度相似值的四舍五入误差,
.skew和.kurt中的错误(GH 11974) -
在
Timestamp构造函数中,如果 HHMMSS 没有用 ':' 分隔,则会丢失微秒分辨率的错误(GH 10041) -
在
buffer_rd_bytes中的错误,如果读取失败,src->buffer 可能会被释放多次,导致段错误(GH 12098) -
在
crosstab中的错误,非重叠索引的参数将返回KeyError(GH 10291) -
在
DataFrame.apply中的错误,未能防止那些dtype不是 numpy dtype 的情况下进行缩减 (GH 12244) -
初始化分类系列时出现错误,带有标量值。 (GH 12336)
-
在
.to_datetime中设置了 UTCDatetimeIndex时出现错误,通过设置utc=True(GH 11934) -
在
read_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 +


浙公网安备 33010602011771号