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) -
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()
中的 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
),并在可能的情况下返回一个category
dtype(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) -
在使用关键字参数时,
groupby
plot
方法中的 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) -
.loc
setitem 索引器中的错误,阻止了使用 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 +