版本 0.15.0 (2014年10月18日)#
这是从 0.14.1 版本以来的一个重大发布,包括少量 API 更改、几个新功能、增强功能和性能改进,以及大量错误修复。我们建议所有用户升级到此版本。
警告
pandas >= 0.15.0 将不再支持与 NumPy 版本 < 1.7.0 的兼容性。如果你想使用最新版本的 pandas,请升级到 NumPy >= 1.7.0 (GH 7711)
亮点包括:
Categorical
类型被整合为一流的 pandas 类型,参见 这里新的标量类型
Timedelta
,以及一个新的索引类型TimedeltaIndex
,请参见 这里新的日期时间类属性访问器
.dt
用于 Series,参见 日期时间类属性新的 DataFrame 默认显示
df.info()
包括内存使用情况,参见 内存使用read_csv
现在在解析时默认忽略空白行,请参见 这里在使用集合操作中的索引时API的变化,请参见 这里
在处理时区的改进,请参见 这里
对滚动和扩展力矩函数的许多改进,请参见 这里
对
Index
类的内部重构,不再子类化ndarray
,参见 内部重构放弃对
PyTables
版本低于 3.0.0 和numexpr
版本低于 2.1 的支持 (GH 7990)将字符串方法文档拆分到 处理文本数据
警告
在 0.15.0 版本中,Index
已经在内部被重构,不再子类化 ndarray
,而是子类化 PandasObject
,与其他 pandas 对象类似。这一改变允许非常容易地进行子类化和创建新的索引类型。这应该是一个透明的改变,只有非常有限的 API 影响(参见 内部重构)
警告
在 Categorical
中的重构将两个参数的构造函数从“代码/标签和级别”改为“值和级别(现在称为‘类别’)”。这可能会导致细微的错误。如果你直接使用 Categorical
,请在更新到这个pandas版本之前审查你的代码,并将其改为使用 from_codes()
构造函数。更多关于 Categorical
的信息请参见 这里
新功能#
序列/数据框中的分类#
Categorical
现在可以包含在 Series
和 DataFrames
中,并且获得了新的方法来操作。感谢 Jan Schulz 为这个 API/实现所做的许多工作。(GH 3943, GH 5313, GH 5314, GH 7444, GH 7839, GH 7848, GH 7864, GH 7914, GH 7768, GH 8006, GH 3678, GH 8075, GH 8076, GH 8143, GH 8453, GH 8518)。
In [1]: df = pd.DataFrame({"id": [1, 2, 3, 4, 5, 6],
...: "raw_grade": ['a', 'b', 'b', 'a', 'a', 'e']})
...:
In [2]: df["grade"] = df["raw_grade"].astype("category")
In [3]: df["grade"]
Out[3]:
0 a
1 b
2 b
3 a
4 a
5 e
Name: grade, Length: 6, dtype: category
Categories (3, object): ['a', 'b', 'e']
# Rename the categories
In [4]: df["grade"] = df["grade"].cat.rename_categories(["very good", "good", "very bad"])
# Reorder the categories and simultaneously add the missing categories
In [5]: df["grade"] = df["grade"].cat.set_categories(["very bad", "bad",
...: "medium", "good", "very good"])
...:
In [6]: df["grade"]
Out[6]:
0 very good
1 good
2 good
3 very good
4 very good
5 very bad
Name: grade, Length: 6, dtype: category
Categories (5, object): ['very bad', 'bad', 'medium', 'good', 'very good']
In [7]: df.sort_values("grade")
Out[7]:
id raw_grade grade
5 6 e very bad
1 2 b good
2 3 b good
0 1 a very good
3 4 a very good
4 5 a very good
[6 rows x 3 columns]
In [8]: df.groupby("grade", observed=False).size()
Out[8]:
grade
very bad 1
bad 0
medium 0
good 2
very good 3
Length: 5, dtype: int64
pandas.core.group_agg
和pandas.core.factor_agg
已被移除。作为替代,构建一个数据框并使用df.groupby(<group>).agg(<func>)
。不再支持向
Categorical
构造函数提供“代码/标签和级别”。现在向构造函数提供两个参数被解释为“值和级别(现在称为‘类别’)”。请更改您的代码以使用from_codes()
构造函数。Categorical.labels
属性已重命名为Categorical.codes
并且是只读的。如果你想操作代码,请使用 Categoricals 的 API 方法 之一。Categorical.levels
属性已重命名为Categorical.categories
。
TimedeltaIndex/标量#
我们引入了一个新的标量类型 Timedelta
,它是 datetime.timedelta
的子类,并且行为类似,但允许与 np.timedelta64
类型兼容,以及许多自定义表示、解析和属性。这种类型与 Timestamp
对 datetimes
的工作方式非常相似。它是一个很好的 API 封装类型。请参阅 文档。 (GH 3009, GH 4533, GH 8209, GH 8187, GH 8190, GH 7869, GH 7661, GH 8345, GH 8471)
警告
Timedelta
标量(和 TimedeltaIndex
)组件字段与 datetime.timedelta
对象的组件字段 不同。例如,datetime.timedelta
对象上的 .seconds
返回 小时
、分钟
和 秒
组合的总秒数。相比之下,pandas 的 Timedelta
分别分解小时、分钟、微秒和纳秒。
# Timedelta accessor
In [9]: tds = pd.Timedelta('31 days 5 min 3 sec')
In [10]: tds.minutes
Out[10]: 5L
In [11]: tds.seconds
Out[11]: 3L
# datetime.timedelta accessor
# this is 5 minutes * 60 + 3 seconds
In [12]: tds.to_pytimedelta().seconds
Out[12]: 303
注意:从 v0.16.0 开始,这不再正确,因为引入了与 datetime.timedelta
的完全兼容性。请参阅 0.16.0 的新增功能条目
警告
在 0.15.0 之前,pd.to_timedelta
对于列表/Series 输入会返回一个 Series
,对于标量输入会返回一个 np.timedelta64
。现在,它将对列表输入返回一个 TimedeltaIndex
,对 Series 输入返回一个 Series
,对标量输入返回一个 Timedelta
。
pd.to_timedelta
的参数现在是 (arg,unit='ns',box=True,coerce=False)
,之前是 (arg,box=True,unit='ns')
,因为这些更符合逻辑。
构建一个标量
In [9]: pd.Timedelta('1 days 06:05:01.00003')
Out[9]: Timedelta('1 days 06:05:01.000030')
In [10]: pd.Timedelta('15.5us')
Out[10]: Timedelta('0 days 00:00:00.000015500')
In [11]: pd.Timedelta('1 hour 15.5us')
Out[11]: Timedelta('0 days 01:00:00.000015500')
# negative Timedeltas have this string repr
# to be more consistent with datetime.timedelta conventions
In [12]: pd.Timedelta('-1us')
Out[12]: Timedelta('-1 days +23:59:59.999999')
# a NaT
In [13]: pd.Timedelta('nan')
Out[13]: NaT
访问 Timedelta
的字段
In [14]: td = pd.Timedelta('1 hour 3m 15.5us')
In [15]: td.seconds
Out[15]: 3780
In [16]: td.microseconds
Out[16]: 15
In [17]: td.nanoseconds
Out[17]: 500
构建一个 TimedeltaIndex
In [18]: pd.TimedeltaIndex(['1 days', '1 days, 00:00:05',
....: np.timedelta64(2, 'D'),
....: datetime.timedelta(days=2, seconds=2)])
....:
Out[18]:
TimedeltaIndex(['1 days 00:00:00', '1 days 00:00:05', '2 days 00:00:00',
'2 days 00:00:02'],
dtype='timedelta64[ns]', freq=None)
使用常规范围构造 TimedeltaIndex
In [19]: pd.timedelta_range('1 days', periods=5, freq='D')
Out[19]: TimedeltaIndex(['1 days', '2 days', '3 days', '4 days', '5 days'], dtype='timedelta64[ns]', freq='D')
In [20]: pd.timedelta_range(start='1 days', end='2 days', freq='30T')
Out[20]:
TimedeltaIndex(['1 days 00:00:00', '1 days 00:30:00', '1 days 01:00:00',
'1 days 01:30:00', '1 days 02:00:00', '1 days 02:30:00',
'1 days 03:00:00', '1 days 03:30:00', '1 days 04:00:00',
'1 days 04:30:00', '1 days 05:00:00', '1 days 05:30:00',
'1 days 06:00:00', '1 days 06:30:00', '1 days 07:00:00',
'1 days 07:30:00', '1 days 08:00:00', '1 days 08:30:00',
'1 days 09:00:00', '1 days 09:30:00', '1 days 10:00:00',
'1 days 10:30:00', '1 days 11:00:00', '1 days 11:30:00',
'1 days 12:00:00', '1 days 12:30:00', '1 days 13:00:00',
'1 days 13:30:00', '1 days 14:00:00', '1 days 14:30:00',
'1 days 15:00:00', '1 days 15:30:00', '1 days 16:00:00',
'1 days 16:30:00', '1 days 17:00:00', '1 days 17:30:00',
'1 days 18:00:00', '1 days 18:30:00', '1 days 19:00:00',
'1 days 19:30:00', '1 days 20:00:00', '1 days 20:30:00',
'1 days 21:00:00', '1 days 21:30:00', '1 days 22:00:00',
'1 days 22:30:00', '1 days 23:00:00', '1 days 23:30:00',
'2 days 00:00:00'],
dtype='timedelta64[ns]', freq='30T')
你现在可以使用 TimedeltaIndex
作为 pandas 对象的索引
In [20]: s = pd.Series(np.arange(5),
....: index=pd.timedelta_range('1 days', periods=5, freq='s'))
....:
In [21]: s
Out[21]:
1 days 00:00:00 0
1 days 00:00:01 1
1 days 00:00:02 2
1 days 00:00:03 3
1 days 00:00:04 4
Freq: s, Length: 5, dtype: int64
你可以通过部分字符串选择进行选择
In [22]: s['1 day 00:00:02']
Out[22]: 2
In [23]: s['1 day':'1 day 00:00:02']
Out[23]:
1 days 00:00:00 0
1 days 00:00:01 1
1 days 00:00:02 2
Freq: s, Length: 3, dtype: int64
最后,TimedeltaIndex
与 DatetimeIndex
的组合允许某些保留 NaT
的组合操作:
In [24]: tdi = pd.TimedeltaIndex(['1 days', pd.NaT, '2 days'])
In [25]: tdi.tolist()
Out[25]: [Timedelta('1 days 00:00:00'), NaT, Timedelta('2 days 00:00:00')]
In [26]: dti = pd.date_range('20130101', periods=3)
In [27]: dti.tolist()
Out[27]:
[Timestamp('2013-01-01 00:00:00'),
Timestamp('2013-01-02 00:00:00'),
Timestamp('2013-01-03 00:00:00')]
In [28]: (dti + tdi).tolist()
Out[28]: [Timestamp('2013-01-02 00:00:00'), NaT, Timestamp('2013-01-05 00:00:00')]
In [29]: (dti - tdi).tolist()
Out[29]: [Timestamp('2012-12-31 00:00:00'), NaT, Timestamp('2013-01-01 00:00:00')]
对
Series
的迭代,例如list(Series(...))
的timedelta64[ns]
在 v0.15.0 之前会为每个元素返回np.timedelta64
。现在这些将被包装在Timedelta
中。
内存使用#
实现了查找 DataFrame 内存使用的方法。更多信息请参见 常见问题解答 (GH 6852)。
一个新的显示选项 display.memory_usage
(见 选项和设置) 设置了 df.info()
方法中 memory_usage
参数的默认行为。默认情况下 display.memory_usage
是 True
。
In [30]: dtypes = ['int64', 'float64', 'datetime64[ns]', 'timedelta64[ns]',
....: 'complex128', 'object', 'bool']
....:
In [31]: n = 5000
In [32]: data = {t: np.random.randint(100, size=n).astype(t) for t in dtypes}
In [33]: df = pd.DataFrame(data)
In [34]: df['categorical'] = df['object'].astype('category')
In [35]: df.info()
<class 'pandas.DataFrame'>
RangeIndex: 5000 entries, 0 to 4999
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 int64 5000 non-null int64
1 float64 5000 non-null float64
2 datetime64[ns] 5000 non-null datetime64[ns]
3 timedelta64[ns] 5000 non-null timedelta64[ns]
4 complex128 5000 non-null complex128
5 object 5000 non-null object
6 bool 5000 non-null bool
7 categorical 5000 non-null category
dtypes: bool(1), category(1), complex128(1), datetime64[ns](1), float64(1), int64(1), object(1), timedelta64[ns](1)
memory usage: 284.1+ KB
此外,memory_usage()
是一个可用于 dataframe 对象的方法,它返回每一列的内存使用情况。
In [36]: df.memory_usage(index=True)
Out[36]:
Index 128
int64 40000
float64 40000
datetime64[ns] 40000
timedelta64[ns] 40000
complex128 80000
object 40000
bool 5000
categorical 5800
Length: 9, dtype: int64
Series.dt 访问器#
Series
获得了一个访问器,可以简洁地返回 values 的类似日期时间的属性,如果它是一个类似日期时间/周期的 Series。(GH 7207) 这将返回一个 Series,索引与现有的 Series 相同。请参阅 文档
# datetime
In [37]: s = pd.Series(pd.date_range('20130101 09:10:12', periods=4))
In [38]: s
Out[38]:
0 2013-01-01 09:10:12
1 2013-01-02 09:10:12
2 2013-01-03 09:10:12
3 2013-01-04 09:10:12
Length: 4, dtype: datetime64[ns]
In [39]: s.dt.hour
Out[39]:
0 9
1 9
2 9
3 9
Length: 4, dtype: int32
In [40]: s.dt.second
Out[40]:
0 12
1 12
2 12
3 12
Length: 4, dtype: int32
In [41]: s.dt.day
Out[41]:
0 1
1 2
2 3
3 4
Length: 4, dtype: int32
In [42]: s.dt.freq
Out[42]: 'D'
这使得像这样的漂亮表达成为可能:
In [43]: s[s.dt.day == 2]
Out[43]:
1 2013-01-02 09:10:12
Length: 1, dtype: datetime64[ns]
你可以轻松地生成时区感知的转换:
In [44]: stz = s.dt.tz_localize('US/Eastern')
In [45]: stz
Out[45]:
0 2013-01-01 09:10:12-05:00
1 2013-01-02 09:10:12-05:00
2 2013-01-03 09:10:12-05:00
3 2013-01-04 09:10:12-05:00
Length: 4, dtype: datetime64[ns, US/Eastern]
In [46]: stz.dt.tz
Out[46]: zoneinfo.ZoneInfo(key='US/Eastern')
你也可以将这些类型的操作链接起来:
In [47]: s.dt.tz_localize('UTC').dt.tz_convert('US/Eastern')
Out[47]:
0 2013-01-01 04:10:12-05:00
1 2013-01-02 04:10:12-05:00
2 2013-01-03 04:10:12-05:00
3 2013-01-04 04:10:12-05:00
Length: 4, dtype: datetime64[ns, US/Eastern]
.dt
访问器适用于 period 和 timedelta 数据类型。
# period
In [48]: s = pd.Series(pd.period_range('20130101', periods=4, freq='D'))
In [49]: s
Out[49]:
0 2013-01-01
1 2013-01-02
2 2013-01-03
3 2013-01-04
Length: 4, dtype: period[D]
In [50]: s.dt.year
Out[50]:
0 2013
1 2013
2 2013
3 2013
Length: 4, dtype: int64
In [51]: s.dt.day
Out[51]:
0 1
1 2
2 3
3 4
Length: 4, dtype: int64
# timedelta
In [52]: s = pd.Series(pd.timedelta_range('1 day 00:00:05', periods=4, freq='s'))
In [53]: s
Out[53]:
0 1 days 00:00:05
1 1 days 00:00:06
2 1 days 00:00:07
3 1 days 00:00:08
Length: 4, dtype: timedelta64[ns]
In [54]: s.dt.days
Out[54]:
0 1
1 1
2 1
3 1
Length: 4, dtype: int64
In [55]: s.dt.seconds
Out[55]:
0 5
1 6
2 7
3 8
Length: 4, dtype: int32
In [56]: s.dt.components
Out[56]:
days hours minutes seconds milliseconds microseconds nanoseconds
0 1 0 0 5 0 0 0
1 1 0 0 6 0 0 0
2 1 0 0 7 0 0 0
3 1 0 0 8 0 0 0
[4 rows x 7 columns]
时区处理改进#
对于时区感知的
Timestamp
和DatetimeIndex
,tz_localize(None)
现在会移除持有本地时间的时区,之前这会导致Exception
或TypeError
(GH 7812)In [58]: ts = pd.Timestamp('2014-08-01 09:00', tz='US/Eastern') In[59]: ts Out[59]: Timestamp('2014-08-01 09:00:00-0400', tz='US/Eastern') In [60]: ts.tz_localize(None) Out[60]: Timestamp('2014-08-01 09:00:00') In [61]: didx = pd.date_range(start='2014-08-01 09:00', freq='H', ....: periods=10, tz='US/Eastern') ....: In [62]: didx Out[62]: DatetimeIndex(['2014-08-01 09:00:00-04:00', '2014-08-01 10:00:00-04:00', '2014-08-01 11:00:00-04:00', '2014-08-01 12:00:00-04:00', '2014-08-01 13:00:00-04:00', '2014-08-01 14:00:00-04:00', '2014-08-01 15:00:00-04:00', '2014-08-01 16:00:00-04:00', '2014-08-01 17:00:00-04:00', '2014-08-01 18:00:00-04:00'], dtype='datetime64[ns, US/Eastern]', freq='H') In [63]: didx.tz_localize(None) Out[63]: DatetimeIndex(['2014-08-01 09:00:00', '2014-08-01 10:00:00', '2014-08-01 11:00:00', '2014-08-01 12:00:00', '2014-08-01 13:00:00', '2014-08-01 14:00:00', '2014-08-01 15:00:00', '2014-08-01 16:00:00', '2014-08-01 17:00:00', '2014-08-01 18:00:00'], dtype='datetime64[ns]', freq=None)
tz_localize
现在接受ambiguous
关键字,该关键字允许传递一个布尔数组,指示日期是否属于夏令时,’NaT’ 用于将过渡时间设置为 NaT,’infer’ 用于推断夏令时/非夏令时,以及 ‘raise’(默认)用于引发AmbiguousTimeError
。更多详情请参见 文档 (GH 7943)DataFrame.tz_localize
和DataFrame.tz_convert
现在接受一个可选的level
参数,用于本地化 MultiIndex 的特定级别 (GH 7846)Timestamp.tz_localize
和Timestamp.tz_convert
现在在错误情况下会引发TypeError
,而不是Exception
(GH 8025)当插入到 Series/DataFrame 时,本地化为 UTC 的时间序列将保留 UTC 时区(而不是天真的
datetime64[ns]
)作为object
数据类型 (GH 8411)Timestamp.__repr__
显示dateutil.tz.tzoffset
信息 (GH 7907)
滚动/扩展时刻改进#
rolling_min()
,rolling_max()
,rolling_cov()
, 和rolling_corr()
现在在len(arg) < min_periods <= window
时返回所有NaN
对象,而不是引发错误。(这使得所有滚动函数在此行为上保持一致)。 (GH 7766)在 0.15.0 之前
In [57]: s = pd.Series([10, 11, 12, 13])
In [15]: pd.rolling_min(s, window=10, min_periods=5) ValueError: min_periods (5) must be <= window (4)
新行为
In [4]: pd.rolling_min(s, window=10, min_periods=5) Out[4]: 0 NaN 1 NaN 2 NaN 3 NaN dtype: float64
rolling_max()
,rolling_min()
,rolling_sum()
,rolling_mean()
,rolling_median()
,rolling_std()
,rolling_var()
,rolling_skew()
,rolling_kurt()
,rolling_quantile()
,rolling_cov()
,rolling_corr()
,rolling_corr_pairwise()
,rolling_window()
, 和rolling_apply()
使用center=True
之前会返回与输入arg
相同结构的结果,但在最后的(window-1)/2
条目中包含NaN
。现在,结果的最后
(window-1)/2
个条目被计算为如果输入arg
后面跟着(window-1)/2
个NaN
值(或者在rolling_apply()
的情况下使用缩小的窗口)。(GH 7925, GH 8269)之前的行为(注意最终值是
NaN
):In [7]: pd.rolling_sum(Series(range(4)), window=3, min_periods=0, center=True) Out[7]: 0 1 1 3 2 6 3 NaN dtype: float64
新行为(注意最终值是
5 = sum([2, 3, NaN])
):In [7]: pd.rolling_sum(pd.Series(range(4)), window=3, ....: min_periods=0, center=True) Out[7]: 0 1 1 3 2 6 3 5 dtype: float64
rolling_window()
现在在滚动平均模式 (mean=True
) 中正确地归一化权重,以便计算的加权平均值(例如 ‘triang’, ‘gaussian’)与未加权计算的平均值(即 ‘boxcar’)分布在相同的均值周围。有关进一步的详细信息,请参见 归一化说明。(GH 7618)In [58]: s = pd.Series([10.5, 8.8, 11.4, 9.7, 9.3])
0.15.0 之前的版本行为:
In [39]: pd.rolling_window(s, window=3, win_type='triang', center=True) Out[39]: 0 NaN 1 6.583333 2 6.883333 3 6.683333 4 NaN dtype: float64
新行为
In [10]: pd.rolling_window(s, window=3, win_type='triang', center=True) Out[10]: 0 NaN 1 9.875 2 10.325 3 10.025 4 NaN dtype: float64
从所有
expanding_
函数中移除了center
参数(见 list),因为当center=True
时产生的结果没有太大意义。(GH 7925)在
expanding_cov()
和rolling_cov()
中添加了可选的ddof
参数。默认值1
是向后兼容的。(GH 8279)记录了
expanding_var()
、expanding_std()
、rolling_var()
和rolling_std()
的ddof
参数。这些函数对ddof
参数(默认值为1
)的支持之前未被记录。(GH 8064)ewma()
,ewmstd()
,ewmvol()
,ewmvar()
,ewmcov()
, 和ewmcorr()
现在以与rolling_*()
和expanding_*()
函数相同的方式解释min_periods
:如果(在这种情况下是扩展的)窗口不包含至少min_periods
个值,则给定的结果条目将为NaN
。之前的行为是将第一个非NaN
值开始的min_periods
个条目设置为NaN
。(GH 7977)先前行为(注意值从索引
2
开始,这是在索引0
(第一个非空值的索引)之后的min_periods
):In [59]: s = pd.Series([1, None, None, None, 2, 3])
In [51]: pd.ewma(s, com=3., min_periods=2) Out[51]: 0 NaN 1 NaN 2 1.000000 3 1.000000 4 1.571429 5 2.189189 dtype: float64
新行为(注意值从索引
4
开始,这是第二个(因为min_periods=2
)非空值的位置):In [2]: pd.ewma(s, com=3., min_periods=2) Out[2]: 0 NaN 1 NaN 2 NaN 3 NaN 4 1.759644 5 2.383784 dtype: float64
ewmstd()
,ewmvol()
,ewmvar()
,ewmcov()
, 和ewmcorr()
现在有一个可选的adjust
参数,就像ewma()
一样,影响权重的计算方式。adjust
的默认值是True
,这是向后兼容的。详情请参见 指数加权矩函数。(GH 7911)ewma()
,ewmstd()
,ewmvol()
,ewmvar()
,ewmcov()
, 和ewmcorr()
现在有一个可选的ignore_na
参数。当 ``ignore_na=False``(默认)时,缺失值在权重计算中被考虑。当 ``ignore_na=True``(这重现了0.15.0之前的行为)时,缺失值在权重计算中被忽略。(GH 7543)In [7]: pd.ewma(pd.Series([None, 1., 8.]), com=2.) Out[7]: 0 NaN 1 1.0 2 5.2 dtype: float64 In [8]: pd.ewma(pd.Series([1., None, 8.]), com=2., ....: ignore_na=True) # pre-0.15.0 behavior Out[8]: 0 1.0 1 1.0 2 5.2 dtype: float64 In [9]: pd.ewma(pd.Series([1., None, 8.]), com=2., ....: ignore_na=False) # new default Out[9]: 0 1.000000 1 1.000000 2 5.846154 dtype: float64
警告
默认情况下 (
ignore_na=False
),ewm*()
函数在存在缺失值时的权重计算与 0.15.0 之前的版本不同。要在存在缺失值时重现 0.15.0 之前的权重计算,必须显式指定ignore_na=True
。在
expanding_cov()
、expanding_corr()
、rolling_cov()
、rolling_cor()
、ewmcov()
和ewmcorr()
中存在一个错误,返回的结果按列名排序,并对非唯一列产生错误;现在处理非唯一列并按原始顺序返回列(除了两个 DataFrame 且pairwise=False
的情况,行为不变)(GH 7542)rolling_count()
和expanding_*()
函数在处理零长度数据时,不必要地产生错误信息 (GH 8056)rolling_apply()
和expanding_apply()
将min_periods=0
解释为min_periods=1
的错误 (GH 8080)对于单个值,
expanding_std()
和expanding_var()
中的错误产生了一个令人困惑的错误消息 (GH 7900)rolling_std()
和rolling_var()
中的错误,对于单个值产生0
而不是NaN
(GH 7900)在
bias=False``(默认值)时,:func:`ewmstd`、:func:`ewmvol`、:func:`ewmvar` 和 :func:`ewmcov` 计算去偏因子时存在错误。之前使用了基于 ``adjust=True
、ignore_na=True
和一个无限数量观测值的错误常数因子。现在每个条目使用不同的因子,基于实际权重(类似于通常的N/(N-1)
因子)。特别是,当bias=False
时,对于单个点返回NaN
值,而之前返回的值大约为0
。例如,考虑以下
ewmvar(..., bias=False)
在0.15.0版本之前的计算结果,以及相应的去偏因子:In [60]: s = pd.Series([1., 2., 0., 4.])
In [89]: pd.ewmvar(s, com=2., bias=False) Out[89]: 0 -2.775558e-16 1 3.000000e-01 2 9.556787e-01 3 3.585799e+00 dtype: float64 In [90]: pd.ewmvar(s, com=2., bias=False) / pd.ewmvar(s, com=2., bias=True) Out[90]: 0 1.25 1 1.25 2 1.25 3 1.25 dtype: float64
注意,条目
0
大约是 0,去偏因子是一个常数 1.25。相比之下,以下 0.15.0 结果在条目0
处有一个NaN
,并且去偏因子在减少(趋向于 1.25):In [14]: pd.ewmvar(s, com=2., bias=False) Out[14]: 0 NaN 1 0.500000 2 1.210526 3 4.089069 dtype: float64 In [15]: pd.ewmvar(s, com=2., bias=False) / pd.ewmvar(s, com=2., bias=True) Out[15]: 0 NaN 1 2.083333 2 1.583333 3 1.425439 dtype: float64
SQL IO 模块的改进#
为
to_sql
函数添加了对chunksize
参数的支持。这允许 DataFrame 以块的形式写入,并避免数据包大小溢出错误 (GH 8062)。为
read_sql
函数添加了对chunksize
参数的支持。指定此参数将返回查询结果块的迭代器(GH 2908)。增加了使用
to_sql
写入datetime.date
和datetime.time
对象列的支持 (GH 6932)。增加了对使用
read_sql_table
和to_sql
时指定schema
的支持(GH 7441, GH 7952)。例如:df.to_sql('table', engine, schema='other_schema') # noqa F821 pd.read_sql_table('table', engine, schema='other_schema') # noqa F821
增加了使用
to_sql
写入NaN
值的支持 (GH 2754)。为所有数据库风格添加了对使用
to_sql
写入 datetime64 列的支持 (GH 7103)。
向后不兼容的 API 更改#
重大变更#
与 Categorical
相关的 API 变化(更多详情见 这里):
Categorical
构造函数从两个参数从“代码/标签和级别”改为“值和级别(现在称为‘类别’)”。这可能导致细微的错误。如果你直接使用Categorical
,请通过将其改为使用from_codes()
构造函数来审计你的代码。一个旧的函数调用(在0.15.0之前):
pd.Categorical([0,1,0,2,1], levels=['a', 'b', 'c'])
将需要适应以下内容以保持相同的行为:
In [2]: pd.Categorical.from_codes([0,1,0,2,1], categories=['a', 'b', 'c']) Out[2]: [a, b, a, c, b] Categories (3, object): [a, b, c]
与引入 Timedelta
标量相关的 API 变化(更多详情请参见 上文):
在 0.15.0 之前,
to_timedelta()
对于类似列表/Series 的输入会返回一个Series
,对于标量输入会返回一个np.timedelta64
。现在它会对类似列表的输入返回一个TimedeltaIndex
,对 Series 输入返回一个Series
,对标量输入返回一个Timedelta
。
有关滚动和扩展函数的API更改,请参见详细概述 上方。
其他值得注意的API变化:
在使用
.loc
和类似列表的索引器进行索引时,当找不到值时的一致性。In [61]: df = pd.DataFrame([['a'], ['b']], index=[1, 2]) In [62]: df Out[62]: 0 1 a 2 b [2 rows x 1 columns]
在之前的版本中,这两种结构是有区别的:
df.loc[[3]]
将返回一个由 3 重新索引的帧(包含所有np.nan
值)df.loc[[3],:]
会引发KeyError
。
两者现在都会引发一个
KeyError
。规则是,在使用类似列表的索引器和.loc
时,必须至少找到 1 个索引器 (GH 7999)此外,在先前版本中这些也是不同的:
df.loc[[1,3]]
将返回一个由 [1,3] 重新索引的框架df.loc[[1,3],:]
会引发KeyError
。
两者现在都将返回一个按 [1,3] 重新索引的帧。例如。
In [3]: df.loc[[1, 3]] Out[3]: 0 1 a 3 NaN In [4]: df.loc[[1, 3], :] Out[4]: 0 1 a 3 NaN
这也可以在带有
Panel
的多轴索引中看到。>>> p = pd.Panel(np.arange(2 * 3 * 4).reshape(2, 3, 4), ... items=['ItemA', 'ItemB'], ... major_axis=[1, 2, 3], ... minor_axis=['A', 'B', 'C', 'D']) >>> p <class 'pandas.core.panel.Panel'> Dimensions: 2 (items) x 3 (major_axis) x 4 (minor_axis) Items axis: ItemA to ItemB Major_axis axis: 1 to 3 Minor_axis axis: A to D
在0.15.0之前,以下代码会引发
KeyError
:In [5]: Out[5]: ItemA ItemD 1 3 NaN 2 7 NaN 3 11 NaN
此外,如果在一个带有类列表索引器的 MultiIndex 中没有找到值,
.loc
将引发错误:In [63]: s = pd.Series(np.arange(3, dtype='int64'), ....: index=pd.MultiIndex.from_product([['A'], ....: ['foo', 'bar', 'baz']], ....: names=['one', 'two']) ....: ).sort_index() ....: In [64]: s Out[64]: one two A bar 1 baz 2 foo 0 Length: 3, dtype: int64 In [65]: try: ....: s.loc[['D']] ....: except KeyError as e: ....: print("KeyError: " + str(e)) ....: KeyError: "['D'] not in index"
现在在为
None
赋值时会考虑 dtype 以选择一个 ‘空’ 值 (GH 7941)。之前,在数值容器中赋值给
None
会将 dtype 改为对象(或根据调用报错)。现在使用NaN
:In [66]: s = pd.Series([1., 2., 3.]) In [67]: s.loc[0] = None In [68]: s Out[68]: 0 NaN 1 2.0 2 3.0 Length: 3, dtype: float64
NaT
现在用于日期时间容器的方式类似。对于对象容器,我们现在保留
None
值(之前这些值被转换为NaN
值)。In [69]: s = pd.Series(["a", "b", "c"]) In [70]: s.loc[0] = None In [71]: s Out[71]: 0 None 1 b 2 c Length: 3, dtype: object
要插入一个
NaN
,你必须显式使用np.nan
。请参阅 文档。在之前的版本中,就地更新 pandas 对象不会反映在对此对象的其他 python 引用中。(GH 8511, GH 5104)
In [72]: s = pd.Series([1, 2, 3]) In [73]: s2 = s In [74]: s += 1.5
v0.15.0 之前的行为
# the original object In [5]: s Out[5]: 0 2.5 1 3.5 2 4.5 dtype: float64 # a reference to the original object In [7]: s2 Out[7]: 0 1 1 2 2 3 dtype: int64
这是现在的正确行为
# the original object In [75]: s Out[75]: 0 2.5 1 3.5 2 4.5 Length: 3, dtype: float64 # a reference to the original object In [76]: s2 Out[76]: 0 2.5 1 3.5 2 4.5 Length: 3, dtype: float64
对于
read_csv
和read_table
的基于C和Python引擎,都忽略输入中的空行以及只要sep
不是空白字符就忽略空白字符填充的行。这是一个可以通过关键字参数skip_blank_lines
控制的API更改。请参阅 文档 (GH 4466)当插入到 Series/DataFrame 时,本地化为 UTC 的时间序列将保留 UTC 时区,并作为
object
数据类型插入,而不是被转换为天真的datetime64[ns]
(GH 8411)。在从字典构造 DataFrame 时,传递带有未保留时区的
DatetimeIndex
的错误 (GH 7822)在之前的版本中,这会丢弃时区,现在它会保留时区,但会给出一列
object
数据类型:In [77]: i = pd.date_range('1/1/2011', periods=3, freq='10s', tz='US/Eastern') In [78]: i Out[78]: DatetimeIndex(['2011-01-01 00:00:00-05:00', '2011-01-01 00:00:10-05:00', '2011-01-01 00:00:20-05:00'], dtype='datetime64[ns, US/Eastern]', freq='10s') In [79]: df = pd.DataFrame({'a': i}) In [80]: df Out[80]: a 0 2011-01-01 00:00:00-05:00 1 2011-01-01 00:00:10-05:00 2 2011-01-01 00:00:20-05:00 [3 rows x 1 columns] In [81]: df.dtypes Out[81]: a datetime64[ns, US/Eastern] Length: 1, dtype: object
之前这会产生一个
datetime64
数据类型列,但没有时区信息。将列分配给现有数据框的行为,如
df['a'] = i
保持不变(这已经返回了一个带有时区的object
列)。当传递多个级别给
stack()
时,如果级别不是所有的级别名称或所有的级别编号,它现在会引发一个ValueError
(GH 7660)。请参见 通过堆叠和解堆重塑。如果在
df.to_hdf
中使用 ‘fixed’ 格式时,df
具有非唯一列,则引发ValueError
,因为生成的文件将会损坏 (GH 7761)SettingWithCopy
根据选项mode.chained_assignment
的设置,现在会在使用链式赋值对混合数据类型的 DataFrame 进行切片赋值时发出 raise/警告。(GH 7845, GH 7950)In [1]: df = pd.DataFrame(np.arange(0, 9), columns=['count']) In [2]: df['group'] = 'b' In [3]: df.iloc[0:5]['group'] = 'a' /usr/local/bin/ipython:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
merge
,DataFrame.merge
, 和ordered_merge
现在返回与left
参数相同的类型 (GH 7737)。之前,使用混合数据类型框架进行扩充的行为与
.append
不同,后者将保留数据类型(相关 GH 2578, GH 8176):In [82]: df = pd.DataFrame([[True, 1], [False, 2]], ....: columns=["female", "fitness"]) ....: In [83]: df Out[83]: female fitness 0 True 1 1 False 2 [2 rows x 2 columns] In [84]: df.dtypes Out[84]: female bool fitness int64 Length: 2, dtype: object # dtypes are now preserved In [85]: df.loc[2] = df.loc[1] In [86]: df Out[86]: female fitness 0 True 1 1 False 2 2 False 2 [3 rows x 2 columns] In [87]: df.dtypes Out[87]: female bool fitness int64 Length: 2, dtype: object
Series.to_csv()
现在在path=None
时返回一个字符串,与DataFrame.to_csv()
的行为相匹配 (GH 8215)。read_hdf
现在在传入一个不存在的文件时会引发IOError
。以前,会创建一个新空文件,并引发KeyError
(GH 7715)。DataFrame.info()
现在以一个换行符结束其输出 (GH 8114)连接没有对象现在会引发一个
ValueError
而不是一个简单的Exception
。合并错误现在将是
ValueError
的子类,而不是原始的Exception
(GH 8501)DataFrame.plot
和Series.plot
关键字的顺序现在是一致的 (GH 8037)
内部重构#
在 0.15.0 版本中,Index
已经在内部被重构,不再继承 ndarray
,而是继承 PandasObject
,类似于其他 pandas 对象。这一改变使得非常容易进行子类化并创建新的索引类型。这应该是一个透明的改变,只有非常有限的 API 影响 (GH 5080, GH 7439, GH 7796, GH 8024, GH 8367, GH 7997, GH 8522):
你可能需要使用
pd.read_pickle
而不是pickle.load
来解封 pandas 版本 < 0.15.0 的 pickle 文件。请参见 pickle 文档在使用
PeriodIndex
绘图时,matplotlib 内部轴现在将是Period
数组,而不是PeriodIndex``(这与 ``DatetimeIndex
现在传递datetimes
数组的方式类似)MultiIndexes 现在在真值测试方面会与其他 pandas 对象类似地引发错误,请参见 这里 (GH 7897)。
当直接使用 matplotlib 的
plot
函数绘制 DatetimeIndex 时,轴标签将不再格式化为日期,而是格式化为整数(datetime64
的内部表示)。更新 这在 0.15.1 版本中已修复,请参见 这里。
弃用#
属性
Categorical
labels
和levels
属性已被弃用,并重命名为codes
和categories
。outtype
参数在pd.DataFrame.to_dict
中已被弃用,取而代之的是orient
。 (GH 7840)convert_dummies
方法已被弃用,取而代之的是get_dummies
(GH 8140)tz_localize
中的infer_dst
参数将被弃用,取而代之的是ambiguous
,以便在处理夏令时转换时提供更大的灵活性。将infer_dst=True
替换为ambiguous='infer'
以获得相同的行为 (GH 7943)。更多详情请参见 文档。顶级
pd.value_range
已被弃用,可以用.describe()
替代 (GH 8481)
Index
集合操作+
和-
已被弃用,以便为某些索引类型的数值操作提供这些操作。+
可以用.union()
或|
替换,-
可以用.difference()
替换。此外,方法名Index.diff()
已被弃用,可以用Index.difference()
替换 (GH 8226)# + pd.Index(['a', 'b', 'c']) + pd.Index(['b', 'c', 'd']) # should be replaced by pd.Index(['a', 'b', 'c']).union(pd.Index(['b', 'c', 'd']))
# - pd.Index(['a', 'b', 'c']) - pd.Index(['b', 'c', 'd']) # should be replaced by pd.Index(['a', 'b', 'c']).difference(pd.Index(['b', 'c', 'd']))
infer_types
参数在read_html()
中现在没有效果并且已被弃用 (GH 7762, GH 7032)。
移除先前版本的弃用/更改#
移除
DataFrame.delevel
方法,改为使用DataFrame.reset_index
增强功能#
在导入/导出 Stata 文件方面的增强:
在
to_stata
中增加了对 bool, uint8, uint16 和 uint32 数据类型的支持 (GH 7097, GH 7365)在导入 Stata 文件时添加了转换选项 (GH 8527)
DataFrame.to_stata
和StataWriter
检查字符串长度以确保与 dta 文件中的限制兼容,其中定宽字符串必须包含 244 个或更少的字符。尝试写入字符串长度超过 244 个字符的 Stata dta 文件会引发ValueError
。 (GH 7858)read_stata
和StataReader
可以通过将参数convert_missing
设置为True
来将缺失数据信息导入DataFrame
。使用此选项时,缺失值将作为StataMissingValue
对象返回,并且包含缺失值的列具有object
数据类型。(GH 8045)
绘图功能的增强:
在
DataFrame.plot
中添加了layout
关键字。你可以传递一个(rows, columns)
的元组,其中一个可以是-1
来自动推断 (GH 6667, GH 8071)。允许将多个轴传递给
DataFrame.plot
、hist
和boxplot
(GH 5353, GH 6970, GH 7069)为
DataFrame.plot
添加了对kind='scatter'
的c
,colormap
和colorbar
参数的支持 (GH 7780)
其他:
read_csv
现在有一个关键字参数float_precision
,它指定在解析期间C引擎应使用哪个浮点转换器,请参见 这里 (GH 8002, GH 8044)在
Series
对象中添加了searchsorted
方法 (GH 7447)describe()
在混合类型的 DataFrame 上更加灵活。现在可以通过include
/exclude
参数进行基于类型的列过滤。请参阅 文档 (GH 8164)。In [88]: df = pd.DataFrame({'catA': ['foo', 'foo', 'bar'] * 8, ....: 'catB': ['a', 'b', 'c', 'd'] * 6, ....: 'numC': np.arange(24), ....: 'numD': np.arange(24.) + .5}) ....: In [89]: df.describe(include=["object"]) Out[89]: catA catB count 24 24 unique 2 4 top foo a freq 16 6 [4 rows x 2 columns] In [90]: df.describe(include=["number", "object"], exclude=["float"]) Out[90]: catA catB numC count 24 24 24.000000 unique 2 4 NaN top foo a NaN freq 16 6 NaN mean NaN NaN 11.500000 std NaN NaN 7.071068 min NaN NaN 0.000000 25% NaN NaN 5.750000 50% NaN NaN 11.500000 75% NaN NaN 17.250000 max NaN NaN 23.000000 [11 rows x 3 columns]
使用简写 ‘all’ 可以请求所有列
In [91]: df.describe(include='all') Out[91]: catA catB numC numD count 24 24 24.000000 24.000000 unique 2 4 NaN NaN top foo a NaN NaN freq 16 6 NaN NaN mean NaN NaN 11.500000 12.000000 std NaN NaN 7.071068 7.071068 min NaN NaN 0.000000 0.500000 25% NaN NaN 5.750000 6.250000 50% NaN NaN 11.500000 12.000000 75% NaN NaN 17.250000 17.750000 max NaN NaN 23.000000 23.500000 [11 rows x 4 columns]
如果没有这些参数,
describe
将像以前一样运行,只包括数值列,或者如果没有数值列,只包括分类列。另请参阅 文档在
pd.DataFrame.to_dict
的orient
参数中添加了split
选项。(GH 7840)get_dummies
方法现在可以用于 DataFrame。默认情况下,只有分类列被编码为 0 和 1,而其他列保持不变。In [92]: df = pd.DataFrame({'A': ['a', 'b', 'a'], 'B': ['c', 'c', 'b'], ....: 'C': [1, 2, 3]}) ....: In [93]: pd.get_dummies(df) Out[93]: C A_a A_b B_b B_c 0 1 True False False True 1 2 False True False True 2 3 True False True False [3 rows x 5 columns]
PeriodIndex
支持与DatetimeIndex
相同的resolution
(GH 7708)pandas.tseries.holiday
增加了对额外假期和观察假期的支持 (GH 7070)pandas.tseries.holiday.Holiday
现在支持 Python3 中的偏移量列表 (GH 7070)pandas.tseries.holiday.Holiday
现在支持一个 days_of_week 参数 (GH 7070)GroupBy.nth()
现在支持选择多个第n个值 (GH 7910)In [94]: business_dates = pd.date_range(start='4/1/2014', end='6/30/2014', freq='B') In [95]: df = pd.DataFrame(1, index=business_dates, columns=['a', 'b']) # get the first, 4th, and last date index for each month In [96]: df.groupby([df.index.year, df.index.month]).nth([0, 3, -1]) Out[96]: a b 2014-04-01 1 1 2014-04-04 1 1 2014-04-30 1 1 2014-05-01 1 1 2014-05-06 1 1 2014-05-30 1 1 2014-06-02 1 1 2014-06-05 1 1 2014-06-30 1 1 [9 rows x 2 columns]
Period
和PeriodIndex
支持与timedelta
类似对象的加减法 (GH 7966)如果
Period
的频率是D
,H
,T
,S
,L
,U
,N
, 当结果可以保持相同频率时,可以添加Timedelta
类似的值。否则,只能添加相同的offsets
。In [104]: idx = pd.period_range('2014-07-01 09:00', periods=5, freq='H') In [105]: idx Out[105]: PeriodIndex(['2014-07-01 09:00', '2014-07-01 10:00', '2014-07-01 11:00', '2014-07-01 12:00', '2014-07-01 13:00'], dtype='period[H]') In [106]: idx + pd.offsets.Hour(2) Out[106]: PeriodIndex(['2014-07-01 11:00', '2014-07-01 12:00', '2014-07-01 13:00', '2014-07-01 14:00', '2014-07-01 15:00'], dtype='period[H]') In [107]: idx + pd.Timedelta('120m') Out[107]: PeriodIndex(['2014-07-01 11:00', '2014-07-01 12:00', '2014-07-01 13:00', '2014-07-01 14:00', '2014-07-01 15:00'], dtype='period[H]') In [108]: idx = pd.period_range('2014-07', periods=5, freq='M') In [109]: idx Out[109]: PeriodIndex(['2014-07', '2014-08', '2014-09', '2014-10', '2014-11'], dtype='period[M]') In [110]: idx + pd.offsets.MonthEnd(3) Out[110]: PeriodIndex(['2014-10', '2014-11', '2014-12', '2015-01', '2015-02'], dtype='period[M]')
增加了与
openpyxl
版本 >= 2.0 的实验性兼容性。DataFrame.to_excel
方法的engine
关键字现在识别openpyxl1
和openpyxl2
,这将分别明确要求 openpyxl v1 和 v2,如果请求的版本不可用则失败。openpyxl
引擎现在是一个元引擎,自动使用已安装的任何版本的 openpyxl。 (GH 7177)DataFrame.fillna
现在可以接受一个DataFrame
作为填充值 (GH 8377)当传递多个层级编号时,
stack()
现在可以正常工作 (GH 7660)。请参见 通过堆叠和解堆叠重塑。set_names()
,set_labels()
, 和set_levels()
方法现在接受一个可选的level
关键字参数,用于修改 MultiIndex 的特定级别。此外,set_names()
现在在操作Index
或MultiIndex
的特定级别时接受一个标量字符串值 (GH 7792)In [97]: idx = pd.MultiIndex.from_product([['a'], range(3), list("pqr")], ....: names=['foo', 'bar', 'baz']) ....: In [98]: idx.set_names('qux', level=0) Out[98]: MultiIndex([('a', 0, 'p'), ('a', 0, 'q'), ('a', 0, 'r'), ('a', 1, 'p'), ('a', 1, 'q'), ('a', 1, 'r'), ('a', 2, 'p'), ('a', 2, 'q'), ('a', 2, 'r')], names=['qux', 'bar', 'baz']) In [99]: idx.set_names(['qux', 'corge'], level=[0, 1]) Out[99]: MultiIndex([('a', 0, 'p'), ('a', 0, 'q'), ('a', 0, 'r'), ('a', 1, 'p'), ('a', 1, 'q'), ('a', 1, 'r'), ('a', 2, 'p'), ('a', 2, 'q'), ('a', 2, 'r')], names=['qux', 'corge', 'baz']) In [100]: idx.set_levels(['a', 'b', 'c'], level='bar') Out[100]: MultiIndex([('a', 'a', 'p'), ('a', 'a', 'q'), ('a', 'a', 'r'), ('a', 'b', 'p'), ('a', 'b', 'q'), ('a', 'b', 'r'), ('a', 'c', 'p'), ('a', 'c', 'q'), ('a', 'c', 'r')], names=['foo', 'bar', 'baz']) In [101]: idx.set_levels([['a', 'b', 'c'], [1, 2, 3]], level=[1, 2]) Out[101]: MultiIndex([('a', 'a', 1), ('a', 'a', 2), ('a', 'a', 3), ('a', 'b', 1), ('a', 'b', 2), ('a', 'b', 3), ('a', 'c', 1), ('a', 'c', 2), ('a', 'c', 3)], names=['foo', 'bar', 'baz'])
Index.isin
现在支持level
参数,以指定用于成员资格测试的索引级别 (GH 7892, GH 7890)In [1]: idx = pd.MultiIndex.from_product([[0, 1], ['a', 'b', 'c']]) In [2]: idx.values Out[2]: array([(0, 'a'), (0, 'b'), (0, 'c'), (1, 'a'), (1, 'b'), (1, 'c')], dtype=object) In [3]: idx.isin(['a', 'c', 'e'], level=1) Out[3]: array([ True, False, True, True, False, True], dtype=bool)
Index
现在支持duplicated
和drop_duplicates
。 (GH 4060)In [102]: idx = pd.Index([1, 2, 3, 4, 1, 2]) In [103]: idx Out[103]: Index([1, 2, 3, 4, 1, 2], dtype='int64') In [104]: idx.duplicated() Out[104]: array([False, False, False, False, True, True]) In [105]: idx.drop_duplicates() Out[105]: Index([1, 2, 3, 4], dtype='int64')
在
pd.concat
中添加copy=True
参数以启用完整块的传递(GH 8252)增加了对 numpy 1.8+ 数据类型(
bool_
、int_
、float_
、string_
)转换为 R dataframe 的支持 (GH 8400)
性能#
在
DatetimeIndex.__iter__
中的性能改进,以允许更快的迭代 (GH 7683)在
Period
创建(和PeriodIndex
setitem)中的性能改进 (GH 5155)在 Series.transform 中改进以实现显著的性能提升(修订) (GH 6496)
在写入大文件时
StataWriter
的性能改进 (GH 8079)多键
groupby
中的性能和内存使用改进 (GH 8128)在 groupby
.agg
和.apply
中,性能改进,其中内置的 max/min 没有映射到 numpy/cythonized 版本 (GH 7722)在写入 sql (
to_sql
) 的性能提升高达 50% (GH 8208)。对于大值 ngroups 的 groupby 性能基准测试 (GH 6787)
在
CustomBusinessDay
和CustomBusinessMonth
中的性能提升 (GH 8236)对于包含日期时间的多级索引,
MultiIndex.values
的性能改进 (GH 8543)
错误修复#
在使用边距和字典aggfunc时,pivot_table中的错误 (GH 8349)
read_csv
中的一个错误,当squeeze=True
时会返回一个视图 (GH 8217)在某些情况下
read_sql
中检查表名时存在错误 (GH 7826)。DataFrame.groupby
中的错误,其中Grouper
在指定频率时不识别级别 (GH 7885)当 DataFrame 保存到 SQL 表时,多索引 dtypes 混淆的错误 (GH 8021)
Series
中浮点数和整数操作数数据类型在0除法中的错误 (GH 7785)Series.astype("unicode")
中的错误未正确调用unicode
处理值 (GH 7758)DataFrame.as_matrix()
中混合datetime64[ns]
和timedelta64[ns]
dtypes 的 Bug (GH 7778)HDFStore.select_column()
中的错误在选择DatetimeIndex
时未保留 UTC 时区信息 (GH 7777)当指定
format='%Y%m%d'
和coerce=True
时,to_datetime
中的错误,之前返回的是对象数组(而不是强制转换的时间序列,包含NaT
),(GH 7930)DatetimeIndex
和PeriodIndex
的就地加法和减法与正常操作的结果不同 (GH 6527)在加减
PeriodIndex
与PeriodIndex
时出现TypeError
的错误 (GH 7741)combine_first
在PeriodIndex
数据中存在错误,引发TypeError
(GH 3367)使用缺失索引器进行 MultiIndex 切片时的错误 (GH 7866)
在各种边缘情况下使用 MultiIndex 切片时的错误 (GH 8132)
在带有非标量类型对象的 MultiIndex 索引中的回归 (GH 7914)
Timestamp
使用==
和int64
dtype 进行比较时的错误 (GH 8058)pickles 中的错误包含
DateOffset
可能在内部引用normalize
属性时引发AttributeError
(GH 7748)当使用
major_xs
和copy=False
时,Panel
中的错误(由于缺少warnings
导致弃用警告失败)(GH 8152)。在反序列化 pickle 时出现的错误,对于带有重复项的 pre-0.14.1 容器失败,试图避免在匹配块和管理器项时的歧义,当只有一个块时没有歧义 (GH 7794)
将
PeriodIndex
放入Series
中的错误会转换为int64
数据类型,而不是Periods
的object
(GH 7932)在传递 where 时
HDFStore
迭代中的 Bug (GH 8014)在传递未排序的键时
DataFrameGroupby.transform
中的错误 (GH 8046, GH 8430)重复的时间序列线和区域图中的错误可能导致
ValueError
或不正确的类型 (GH 7733)在
MultiIndex
中使用datetime.date
输入的推理错误 (GH 7888)get
中的一个错误,其中IndexError
不会导致返回默认值 (GH 7725)offsets.apply
,rollforward
和rollback
中的错误可能会重置纳秒 (GH 7697)offsets.apply
、rollforward
和rollback
中的错误可能会在Timestamp
具有dateutil
tzinfo 时引发AttributeError
(GH 7697)在带有
Float64Index
的多索引框架中排序的错误 (GH 8017)在为对齐设置
DataFrame
的 rhs 时,面板 setitem 不一致的错误 (GH 7763)is_superperiod
和is_subperiod
中的错误无法处理高于S
的频率(GH 7760, GH 7772, GH 7803)32位平台上的
Series.shift
错误 (GH 8129)PeriodIndex.unique
中的错误返回 int64np.ndarray
(GH 7540)groupby.apply
中在函数中存在不影响结果的突变的问题 (GH 8467)DataFrame.reset_index
中的错误,当MultiIndex
包含PeriodIndex
或带时区的DatetimeIndex
时会引发ValueError
(GH 7746, GH 7793)在
DataFrame.plot
中使用subplots=True
时可能会绘制不必要的次要 xticks 和 yticks (GH 7801)StataReader
中的一个错误,由于 Stata 文档和实现之间的差异,导致无法读取 117 个文件中的变量标签 (GH 7816)StataReader
中的一个错误,其中字符串总是被转换为244个字符的固定宽度,而不考虑底层字符串的大小 (GH 7858)DataFrame.plot
和Series.plot
中的错误可能会忽略rot
和fontsize
关键字 (GH 7844)DatetimeIndex.value_counts
中的错误不保留时区 (GH 7735)PeriodIndex.value_counts
中的错误导致Int64Index
(GH 7735)在
DataFrame.join
中进行索引左连接且存在多个匹配项时的错误 (GH 5391)在
GroupBy.transform()
中存在一个错误,当使用不保留索引的转换对整数组进行分组时,结果会被错误地截断 (GH 7972)。groupby
中的一个错误,其中没有名称属性的可调用对象会走错路径,并生成一个DataFrame
而不是一个Series
(GH 7929)当 DataFrame 分组列重复时
groupby
错误信息中的 Bug (GH 7511)read_html
中的一个错误,其中infer_types
参数强制将日期类型错误地转换 (GH 7762, GH 7032)。Series.str.cat
中存在一个错误,该错误发生在索引被过滤为不包括第一个项目的情况下 (GH 7857)Timestamp
中的错误无法从字符串解析nanosecond
(GH 7878)Timestamp
中带有字符串偏移和tz
导致结果不正确 (GH 7833)tslib.tz_convert
和tslib.tz_convert_single
中的错误可能会返回不同的结果 (GH 7798)在
DatetimeIndex.intersection
中,非重叠时间戳与时区引发IndexError
(GH 7880)与 TimeOps 对齐的错误和非唯一索引 (GH 8363)
GroupBy.filter()
中的一个错误,快速路径与慢速路径导致过滤器返回一个看似有效但不是标量的值(GH 7870)。当从输入日期推断时区时,在跨越夏令时边界时
date_range()
/DatetimeIndex()
中的错误导致返回了不正确的时间 (GH 7835, GH 7901)。to_excel()
中的一个错误,正无穷大前加了一个负号,而负无穷大前没有负号 (GH 7949)当
stacked=True
时,区域图中的错误会在图例中以不正确的alpha
绘制 (GH 8027)Period
和PeriodIndex
与np.timedelta64
的加减运算导致内部表示不正确 (GH 7740)Holiday
中没有偏移或遵守的错误 (GH 7987)当列或索引是
MultiIndex
时,DataFrame.to_latex
格式化中的错误 (GH 7982)。DateOffset
在夏令时附近的错误产生意外结果 (GH 5175)。DataFrame.shift
中的一个错误,在 numpy 1.7 上会导致空列抛出ZeroDivisionError
(GH 8019)安装中的一个错误,其中
html_encoding/*.html
没有被安装,因此一些测试没有正确运行 (GH 7927)。在
read_html
中的bytes
对象在_read
中未被测试的错误 (GH 7927)。当其中一个列级别是类似日期时,
DataFrame.stack()
中的错误 (GH 8039)在
DataFrame
中广播 numpy 标量时出现错误 (GH 8116)在
pivot_table
中使用无名的index
和columns
会引发KeyError
(GH 8103)DataFrame.plot(kind='scatter')
中的错误在指定颜色时,点的颜色和误差条的颜色不同,当颜色由c
关键字指定时 (GH 8081)Float64Index
中的错误,其中iat
和at
未经过测试并失败 (GH 8092)。在
DataFrame.boxplot()
中存在一个错误,当生成多个轴时,y 轴限制设置不正确 (GH 7528, GH 5517)。read_csv
中的一个错误,当给定自定义行终止符或delim_whitespace=True
时,行注释未正确处理 (GH 8122)。read_html
中的一个错误,空表导致StopIteration
(GH 7575)在设置相同数据类型块中的列时进行类型转换的错误 (GH 7704)
当原始分组器是一个元组时,从
GroupBy
访问组的错误 (GH 8121)。.at
中的一个错误,该错误会在非整数索引上接受整数索引器并进行回退 (GH 7814)kde 图和 NaN 的错误 (GH 8182)
在
GroupBy.count
中使用 float32 数据类型时,nan 值未被排除的错误 (GH 8169)。带有堆叠条形图和 NaNs 的错误 (GH 8175)。
在非均匀可除偏移量(例如 ‘7s’)下的重采样错误 (GH 8371)
在使用
limit
关键字时的插值方法中存在错误,当不需要插值时 (GH 7173)。当
header=False
时,col_space
在DataFrame.to_string()
中被忽略的错误 (GH 8230)。DatetimeIndex.asof
的错误,错误地匹配部分字符串并返回错误的日期 (GH 8245)。绘图方法中修改全局 matplotlib rcParams 的错误 (GH 8242)。
在
DataFrame.__setitem__
中的一个错误,当将数据框列设置为稀疏数组时会导致错误 (GH 8131)当整个列都为空时,
Dataframe.boxplot()
失败的错误 (GH 8181)。radviz
可视化中变量混乱的错误 (GH 8199)。在使用
limit
关键字时的插值方法中存在错误,当不需要插值时 (GH 7173)。当
header=False
时,col_space
在DataFrame.to_string()
中被忽略的错误 (GH 8230)。to_clipboard
中的错误会导致长列数据被剪切 (GH 8305)DataFrame
终端显示中的错误:将 max_column/max_rows 设置为零不会触发 dfs 自动调整以适应终端宽度/高度 (GH 7180)。在OLS中的一个错误,使用“cluster”和“nw_lags”参数运行时没有正确工作,但也没有抛出错误 (GH 5884)。
DataFrame.dropna
中的一个错误,将子集参数中不存在的列解释为 ‘最后一列’ (GH 8303)在非单调非唯一索引上的
Index.intersection
错误 (GH 8362)。在掩码系列赋值中存在一个错误,当类型不匹配时会破坏对齐 (GH 8387)
NDFrame.equals
中的错误在 dtype=object 时给出假阴性 (GH 8437)在索引器赋值中的错误,类型多样性会破坏对齐 (GH 8258)
当目标是一个列表/ndarray时,
NDFrame.loc
索引中的错误导致行/列名称丢失 (GH 6552)当行/列转换为 Float64Index 时,
NDFrame.loc
索引中的回归,如果目标是空列表/ndarray (GH 7774)Series
中的一个错误,允许它通过一个会产生意外结果的DataFrame
进行索引。这种索引不再被允许 (GH 8444)在具有 MultiIndex 列的
DataFrame
的项目分配中存在一个错误,其中右侧列未对齐 (GH 7655)在比较包含 NaN 的对象数组时抑制由 NumPy 生成的 FutureWarning (GH 7065)
DataFrame.eval()
中的一个错误,其中not
运算符 (~
) 的 dtype 没有被正确推断为bool
。
贡献者#
总共有80人为此版本贡献了补丁。名字后面带有“+”的人首次贡献了补丁。
Aaron Schumacher +
Adam Greenhall
Andy Hayden
Anthony O’Brien +
Artemy Kolchinsky +
Ben Schiller +
Benedikt Sauer
Benjamin Thyreau +
BorisVerk +
Chris Reynolds +
Chris Stoafer +
DSM
Dav Clark +
FragLegs +
German Gomez-Herrero +
Hsiaoming Yang +
Huan Li +
Hyungtae Kim +
Isaac Slavitt +
Jacob Schaer
Jacob Wasserman +
Jan Schulz
Jeff Reback
Jeff Tratner
Jesse Farnham +
Joe Bradish +
Joerg Rittinger +
John W. O’Brien
Joris Van den Bossche
Kevin Sheppard
Kyle Meyer
Max Chang +
Michael Mueller
Michael W Schatzow +
Mike Kelly
Mortada Mehyar
Nathan Sanders +
Nathan Typanski +
Paul Masurel +
Phillip Cloud
Pietro Battiston
RenzoBertocchi +
Ross Petchler +
Shahul Hameed +
Shashank Agarwal +
Stephan Hoyer
Tom Augspurger
TomAugspurger
Tony Lorenzo +
Wes Turner
Wilfred Hughes +
Yevgeniy Grechka +
Yoshiki Vázquez Baeza +
behzad nouri +
benjamin
bjonen +
dlovell +
dsm054
hunterowens +
immerrr
ischwabacher
jmorris0x0 +
jnmclarty +
jreback
klonuo +
lexual
mcjcode +
mtrbean +
onesandzeroes
rockg
seth-p
sinhrks
someben +
stahlous +
stas-sl +
thatneat +
tom-alcorn +
unknown
unutbu
zachcp +