版本0.15.0(2014年10月18日)#

这是从0.14.1开始的一个主要版本,包括少量的API更改、几个新功能、增强功能和性能改进,以及大量的错误修复。我们建议所有用户升级到此版本。

警告

Pandas>=0.15.0将不再支持与低于1.7.0的NumPy版本兼容。如果您想使用最新版本的Pandas,请升级到NumPy>=1.7.0 (GH7711 )

警告

在0.15.0中 Index 已在内部重构为不再是子类 ndarray 取而代之的是子类 PandasObject ,类似于其他大Pandas的物体。此更改允许非常轻松地进行子类划分和创建新的索引类型。这应该是一个透明的更改,对API的影响非常有限(请参阅 Internal Refactoring )

警告

中的重构 Categorical 将两个参数构造函数从“代码/标签和级别”更改为“值和级别(现在称为‘类别’)”。这可能会导致细微的错误。如果您使用 Categorical 请在更新到此PANAS版本之前直接审核您的代码,并将其更改为使用 from_codes() 构造函数。请参阅更多信息 Categorical here

新功能#

系列/数据框架中的分类#

Categorical 现在可以包含在 SeriesDataFrames 并获得了新的操纵方法。感谢Jan Schulz在此API/实现中所做的大部分工作。 (GH3943GH5313GH5314GH7444GH7839GH7848GH7864GH7914GH7768GH8006GH3678GH8075GH8076GH8143GH8453GH8518 )。

有关完整的文档,请参阅 categorical introduction 以及 API documentation

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"].cat.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").size()
Out[8]: 
grade
very bad     1
bad          0
medium       0
good         2
very good    3
Length: 5, dtype: int64
  • pandas.core.group_aggpandas.core.factor_agg 都被移除了。作为替代方案,构建数据帧并使用 df.groupby(<group>).agg(<func>)

  • 提供“代码/标签和级别”给 Categorical 不再支持构造函数。向构造函数提供两个参数现在被解释为“值和级别(现在称为‘类别’)”。请更改您的代码以使用 from_codes() 构造函数。

  • 这个 Categorical.labels 属性已重命名为 Categorical.codes 并且是只读的。如果您想要操纵代码,请使用 API methods on Categoricals

  • 这个 Categorical.levels 属性被重命名为 Categorical.categories

时间索引/标量#

我们引入了一种新的标量类型 Timedelta ,它是的子类 datetime.timedelta ,并以类似方式运行,但允许与 np.timedelta64 类型以及大量的自定义表示、解析和属性。此类型非常类似于 Timestamp 为以下公司工作 datetimes 。对于这种类型来说,这是一个很好的API盒。请参阅 docs 。 (GH3009GH4533GH8209GH8187GH8190GH7869GH7661GH8345GH8471 )

警告

Timedelta 标量(和 TimedeltaIndex )组件字段为 不一样 对象上的组件字段 datetime.timedelta 对象。例如, .seconds 在一个 datetime.timedelta 对象返回 hoursminutesseconds 。相比之下,大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

Note :从v0.16.0开始不再是这样,完全兼容 datetime.timedelta 介绍了它的基本原理和特点。请参阅 0.16.0 whatsnew entry

警告

0.15.0之前的版本 pd.to_timedelta 将返回一个 Series 用于类似列表的/系列输入,以及 np.timedelta64 用于标量输入。它现在将返回一个 TimedeltaIndex 对于列表式输入, 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 [21]: s = pd.Series(np.arange(5),
   ....:               index=pd.timedelta_range('1 days', periods=5, freq='s'))
   ....: 

In [22]: s
Out[22]: 
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 [23]: s['1 day 00:00:02']
Out[23]: 2

In [24]: s['1 day':'1 day 00:00:02']
Out[24]: 
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 [25]: tdi = pd.TimedeltaIndex(['1 days', pd.NaT, '2 days'])

In [26]: tdi.tolist()
Out[26]: [Timedelta('1 days 00:00:00'), NaT, Timedelta('2 days 00:00:00')]

In [27]: dti = pd.date_range('20130101', periods=3)

In [28]: dti.tolist()
Out[28]: 
[Timestamp('2013-01-01 00:00:00', freq='D'),
 Timestamp('2013-01-02 00:00:00', freq='D'),
 Timestamp('2013-01-03 00:00:00', freq='D')]

In [29]: (dti + tdi).tolist()
Out[29]: [Timestamp('2013-01-02 00:00:00'), NaT, Timestamp('2013-01-05 00:00:00')]

In [30]: (dti - tdi).tolist()
Out[30]: [Timestamp('2012-12-31 00:00:00'), NaT, Timestamp('2013-01-01 00:00:00')]
  • A的迭代 Series 例如: list(Series(...))timedelta64[ns] 将在v0.15.0之前返回 np.timedelta64 对于每个元素。现在,这些将被包裹在 Timedelta

内存使用情况#

实现了用于查找DataFrame的内存使用情况的方法。请参阅 FAQ 想要更多。 (GH6852 )。

一个新的显示选项 display.memory_usage (请参阅 选项和设置 )设置 memory_usage 中的参数 df.info() 方法。默认情况下 display.memory_usageTrue

In [31]: dtypes = ['int64', 'float64', 'datetime64[ns]', 'timedelta64[ns]',
   ....:           'complex128', 'object', 'bool']
   ....: 

In [32]: n = 5000

In [33]: data = {t: np.random.randint(100, size=n).astype(t) for t in dtypes}

In [34]: df = pd.DataFrame(data)

In [35]: df['categorical'] = df['object'].astype('category')

In [36]: df.info()
<class 'pandas.core.frame.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: 288.2+ KB

另外 memory_usage() 是DataFrame对象的可用方法,它返回每列的内存使用情况。

In [37]: df.memory_usage(index=True)
Out[37]: 
Index                128
int64              40000
float64            40000
datetime64[ns]     40000
timedelta64[ns]    40000
complex128         80000
object             40000
bool                5000
categorical         9968
Length: 9, dtype: int64

Series.dt访问器#

Series has gained an accessor to succinctly return datetime like properties for the values of the Series, if its a datetime/period like Series. (GH7207) This will return a Series, indexed like the existing Series. See the docs

# datetime
In [38]: s = pd.Series(pd.date_range('20130101 09:10:12', periods=4))

In [39]: s
Out[39]: 
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 [40]: s.dt.hour
Out[40]: 
0    9
1    9
2    9
3    9
Length: 4, dtype: int64

In [41]: s.dt.second
Out[41]: 
0    12
1    12
2    12
3    12
Length: 4, dtype: int64

In [42]: s.dt.day
Out[42]: 
0    1
1    2
2    3
3    4
Length: 4, dtype: int64

In [43]: s.dt.freq
Out[43]: 'D'

这样就可以使用下面这样的漂亮表达:

In [44]: s[s.dt.day == 2]
Out[44]: 
1   2013-01-02 09:10:12
Length: 1, dtype: datetime64[ns]

您可以轻松地生成TZ感知转换:

In [45]: stz = s.dt.tz_localize('US/Eastern')

In [46]: stz
Out[46]: 
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 [47]: stz.dt.tz
Out[47]: <DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>

您还可以链接以下类型的操作:

In [48]: s.dt.tz_localize('UTC').dt.tz_convert('US/Eastern')
Out[48]: 
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 [49]: s = pd.Series(pd.period_range('20130101', periods=4, freq='D'))

In [50]: s
Out[50]: 
0    2013-01-01
1    2013-01-02
2    2013-01-03
3    2013-01-04
Length: 4, dtype: period[D]

In [51]: s.dt.year
Out[51]: 
0    2013
1    2013
2    2013
3    2013
Length: 4, dtype: int64

In [52]: s.dt.day
Out[52]: 
0    1
1    2
2    3
3    4
Length: 4, dtype: int64
# timedelta
In [53]: s = pd.Series(pd.timedelta_range('1 day 00:00:05', periods=4, freq='s'))

In [54]: s
Out[54]: 
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 [55]: s.dt.days
Out[55]: 
0    1
1    1
2    1
3    1
Length: 4, dtype: int64

In [56]: s.dt.seconds
Out[56]: 
0    5
1    6
2    7
3    8
Length: 4, dtype: int64

In [57]: s.dt.components
Out[57]: 
   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]

改进时区处理#

  • tz_localize(None) for tz-aware Timestamp and DatetimeIndex now removes timezone holding local time, previously this resulted in Exception or TypeError (GH7812)

    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 允许传递指示日期是否属于DST的布尔数组的关键字,用于将转换时间设置为NAT的‘NAT’,用于推断DST/非DST的‘INFER’,以及用于 AmbiguousTimeError 被抚养长大。看见 the docs 获取更多详细信息 (GH7943 )

  • DataFrame.tz_localizeDataFrame.tz_convert 现在接受可选的 level 用于本地化多重索引的特定级别的参数 (GH7846 )

  • Timestamp.tz_localize and Timestamp.tz_convert now raise TypeError in error cases, rather than Exception (GH8025)

  • 在插入到Series/DataFrame中时,本地化为UTC的TimeSeries/Index将保留UTC时区(而不是幼稚的 datetime64[ns] )AS object 数据类型 (GH8411 )

  • Timestamp.__repr__ 显示 dateutil.tz.tzoffset 信息 (GH7907 )

滚动/扩展力矩的改进#

  • rolling_min()rolling_max()rolling_cov() ,以及 rolling_corr() 现在返回包含所有 NaN 什么时候 len(arg) < min_periods <= window 而不是提高。(这使所有滚动函数在此行为中保持一致)。 (GH7766 )

    0.15.0之前的版本

    In [64]: 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 使用 NaN 在决赛中 (window-1)/2 条目。

    现在是决赛 (window-1)/2 结果的条目被计算为好像输入 arg 紧随其后的是 (window-1)/2 NaN 值(或缩小窗口,如果是 rolling_apply() )。 (GH7925GH8269 )

    之前的行为(请注意,最终值为 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’、‘Gauss’)与未加权计算的平均值(即‘Boxcar’)分布相同。看见 the note on normalization 了解更多详细信息。 (GH7618 )

    In [65]: 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
    
  • 已删除 center 来自所有人的论点 expanding_ 函数(请参见 list )时产生的结果 center=True 这没有多大意义。 (GH7925 )

  • 添加了可选选项 ddof 参数为 expanding_cov()rolling_cov() 。的默认值 1 是向后兼容的。 (GH8279 )

  • 记录了 ddof 参数为 expanding_var()expanding_std()rolling_var() ,以及 rolling_std() 。这些函数对 ddof 参数(缺省值为 1 )之前是没有记录的。 (GH8064 )

  • ewma()ewmstd()ewmvol()ewmvar()ewmcov() ,以及 ewmcorr() 现在解释一下 min_periods 以相同的方式 rolling_*()expanding_*() 函数执行:给定的结果条目将是 NaN 如果(在本例中为扩展)窗口不包含至少 min_periods 价值观。之前的行为是设置为 NaN 这个 min_periods 条目以第一个非- NaN 价值。 (GH7977 )

    以前的行为(注意,值从索引开始 2 ,即 min_periods 后置索引 0 (第一个非空值的索引):

    In [66]: 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 ,2号的位置(自 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() 会影响权重的计算方式。的默认值为 adjustTrue 它是向后兼容的。看见 Exponentially weighted moment functions 有关详细信息,请参阅。 (GH7911 )

  • ewma()ewmstd()ewmvol()ewmvar()ewmcov() ,以及 ewmcorr() 现在有一个可选的 ignore_na 争论。什么时候 ignore_na=False (默认设置),则在权重计算中会考虑缺少的值。什么时候 ignore_na=True (它再现0.15.0之前的行为),则在权重计算中忽略缺少的值。 (GH7543 )

    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() 返回按名称排序的列的结果,并为非唯一列生成错误;现在处理非唯一列并按原始顺序返回列(具有 pairwise=False ,其中行为保持不变) (GH7542 )

  • 窃听 rolling_count()expanding_*() 不必要地为零长度数据生成错误消息的函数 (GH8056 )

  • Bug in rolling_apply() and expanding_apply() interpreting min_periods=0 as min_periods=1 (GH8080)

  • 窃听 expanding_std()expanding_var() 对于产生令人困惑的错误消息的单个值 (GH7900 )

  • Bug in rolling_std() and rolling_var() for a single value producing 0 rather than NaN (GH7900)

  • 窃听 ewmstd()ewmvol()ewmvar() ,以及 ewmcov() 在以下情况下去偏系数的计算 bias=False (默认设置)。以前使用了不正确的常量因数,基于 adjust=Trueignore_na=True ,以及无数次的观测。现在,根据实际权重对每个条目使用不同的系数(类似于通常的 N/(N-1) 因数)。特别是,对于单个点,值为 NaN 在以下情况下返回 bias=False ,而之前的值为(大约) 0 被退回了。

    例如,考虑以下0.15.0之前版本的结果 ewmvar(..., bias=False) ,以及相应的去偏系数:

    In [67]: 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结果具有 NaN 对于条目 0 ,且去偏系数正在减小(接近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
    

    看见 Exponentially weighted moment functions 有关详细信息,请参阅。 (GH7912 )

改进了SQL IO模块#

  • 添加了对 chunksize 参数设置为 to_sql 功能。这允许以块为单位写入DataFrame,并避免数据包大小的溢出错误 (GH8062 )。

  • 添加了对 chunksize 参数设置为 read_sql 功能。指定此参数将返回遍历查询结果块的迭代器 (GH2908 )。

  • Added support for writing datetime.date and datetime.time object columns with to_sql (GH6932).

  • Added support for specifying a schema to read from/write to with read_sql_table and to_sql (GH7441, GH7952). For example:

    df.to_sql('table', engine, schema='other_schema')  # noqa F821
    pd.read_sql_table('table', engine, schema='other_schema')  # noqa F821
    
  • Added support for writing NaN values with to_sql (GH2754).

  • 添加了对写入Datetime64列的支持 to_sql 适用于所有数据库风格 (GH7103 )。

向后不兼容的API更改#

突破性变化#

与以下内容相关的API更改 Categorical (请参阅 here 有关更多详细信息):

  • 这个 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]
    

API的更改与引入 Timedelta 标量(请参见 above 有关更多详细信息):

  • 0.15.0之前的版本 to_timedelta() 将返回一个 Series 用于类似列表的/系列输入,以及 np.timedelta64 用于标量输入。它现在将返回一个 TimedeltaIndex 对于列表式输入, Series 对于串联输入,和 Timedelta 用于标量输入。

关于滚动和扩展函数相关的接口更改,请参见详细概述 above

其他值得注意的API变化:

  • 使用索引时的一致性 .loc 以及在未找到值时使用类似列表的索引器。

    In [68]: df = pd.DataFrame([['a'], ['b']], index=[1, 2])
    
    In [69]: df
    Out[69]: 
       0
    1  a
    2  b
    
    [2 rows x 1 columns]
    

    在以前的版本中,这两个结构有所不同:

    • df.loc[[3]] 将返回重新索引为3的帧(所有 np.nan 值)

    • df.loc[[3],:] 会募集到 KeyError

    Both will now raise a KeyError. The rule is that at least 1 indexer must be found when using a list-like and .loc (GH7999)

    此外,在以前的版本中,这些也不同:

    • 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
    

    下面的内容将引发 KeyError 0.15.0之前的版本:

    In [5]:
    Out[5]:
       ItemA  ItemD
    1      3    NaN
    2      7    NaN
    3     11    NaN
    

    此外, .loc 如果在具有类似列表的索引器的多索引中找不到值,将引发:

    In [70]: s = pd.Series(np.arange(3, dtype='int64'),
       ....:               index=pd.MultiIndex.from_product([['A'],
       ....:                                                ['foo', 'bar', 'baz']],
       ....:                                                names=['one', 'two'])
       ....:               ).sort_index()
       ....: 
    
    In [71]: s
    Out[71]: 
    one  two
    A    bar    1
         baz    2
         foo    0
    Length: 3, dtype: int64
    
    In [72]: try:
       ....:     s.loc[['D']]
       ....: except KeyError as e:
       ....:     print("KeyError: " + str(e))
       ....: 
    KeyError: "['D'] not in index"
    
  • 将值赋给 None 现在选择‘Empty’值时会考虑数据类型 (GH7941 )。

    以前,将分配给 None 在数字容器中,将数据类型更改为对象(或错误,取决于调用)。它现在使用的是 NaN

    In [73]: s = pd.Series([1, 2, 3])
    
    In [74]: s.loc[0] = None
    
    In [75]: s
    Out[75]: 
    0    NaN
    1    2.0
    2    3.0
    Length: 3, dtype: float64
    

    NaT 现在类似地用于DateTime容器。

    对于对象容器,我们现在保留 None 值(以前这些值被转换为 NaN 值)。

    In [76]: s = pd.Series(["a", "b", "c"])
    
    In [77]: s.loc[0] = None
    
    In [78]: s
    Out[78]: 
    0    None
    1       b
    2       c
    Length: 3, dtype: object
    

    要插入一个 NaN ,则必须显式使用 np.nan 。请参阅 docs

  • 在以前的版本中,就地更新Pandas对象不会反映在对该对象的其他Python引用中。 (GH8511GH5104 )

    In [79]: s = pd.Series([1, 2, 3])
    
    In [80]: s2 = s
    
    In [81]: 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 [82]: s
    Out[82]: 
    0    2.5
    1    3.5
    2    4.5
    Length: 3, dtype: float64
    
    # a reference to the original object
    In [83]: s2
    Out[83]: 
    0    2.5
    1    3.5
    2    4.5
    Length: 3, dtype: float64
    
  • Made both the C-based and Python engines for read_csv and read_table ignore empty lines in input as well as white space-filled lines, as long as sep is not white space. This is an API change that can be controlled by the keyword parameter skip_blank_lines. See the docs (GH4466)

  • A timeseries/index localized to UTC when inserted into a Series/DataFrame will preserve the UTC timezone and inserted as object dtype rather than being converted to a naive datetime64[ns] (GH8411).

  • 在传递一个 DatetimeIndex 具有在从DICT构造DataFrame时未保留的时区 (GH7822 )

    在以前的版本中,这将删除时区,现在它保留时区,但提供一列 object 数据类型:

    In [84]: i = pd.date_range('1/1/2011', periods=3, freq='10s', tz='US/Eastern')
    
    In [85]: i
    Out[85]: 
    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 [86]: df = pd.DataFrame({'a': i})
    
    In [87]: df
    Out[87]: 
                              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 [88]: df.dtypes
    Out[88]: 
    a    datetime64[ns, US/Eastern]
    Length: 1, dtype: object
    

    以前,这会产生一列 datetime64 Dtype,但没有时区信息。

    将列分配给现有数据帧的行为为 df['a'] = i 保持不变(这已返回一个 object 具有时区的列)。

  • 将多个级别传递给 stack() ,它现在将提高一个 ValueError 当级别不是所有级别名称或级别编号时 (GH7660 )。看见 Reshaping by stacking and unstacking

  • 提高一名 ValueError 在……里面 df.to_hdf 使用‘FIXED’格式,如果 df 具有非唯一列,因为结果文件将被破坏 (GH7761 )

  • SettingWithCopy 提高/警告(根据选项 mode.chained_assignment 现在,当使用链接赋值在切片的混合dtype DataFrame上设置值时,将发出。 (GH7845GH7950 )

    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
    
  • mergeDataFrame.merge ,以及 ordered_merge 现在返回与 left 论据 (GH7737 )。

  • 以前,使用混合dtype框架的放大操作不同于 .append 它将保留数据类型(相关 GH2578GH8176 ):

    In [89]: df = pd.DataFrame([[True, 1], [False, 2]],
       ....:                   columns=["female", "fitness"])
       ....: 
    
    In [90]: df
    Out[90]: 
       female  fitness
    0    True        1
    1   False        2
    
    [2 rows x 2 columns]
    
    In [91]: df.dtypes
    Out[91]: 
    female      bool
    fitness    int64
    Length: 2, dtype: object
    
    # dtypes are now preserved
    In [92]: df.loc[2] = df.loc[1]
    
    In [93]: df
    Out[93]: 
       female  fitness
    0    True        1
    1   False        2
    2   False        2
    
    [3 rows x 2 columns]
    
    In [94]: df.dtypes
    Out[94]: 
    female      bool
    fitness    int64
    Length: 2, dtype: object
    
  • Series.to_csv() now returns a string when path=None, matching the behaviour of DataFrame.to_csv() (GH8215).

  • read_hdf 现在提高 IOError 当传入一个不存在的文件时。以前,创建了一个新的空文件,并且 KeyError 已提高 (GH7715 )。

  • DataFrame.info() 现在以换行符结束其输出 (GH8114 )

  • 现在,连接任何对象都将引发 ValueError 而不是光秃秃的 Exception

  • Merge errors will now be sub-classes of ValueError rather than raw Exception (GH8501)

  • DataFrame.plotSeries.plot 关键字现在具有一致的顺序 (GH8037 )

内部重构#

在0.15.0中 Index 已在内部重构为不再是子类 ndarray 取而代之的是子类 PandasObject ,类似于其他大Pandas的物体。此更改允许非常轻松地进行子类划分和创建新的索引类型。这应该是一个透明的更改,对API的影响非常有限 (GH5080GH7439GH7796GH8024GH8367GH7997GH8522 ):

  • 您可能需要使用以下工具来取消对低于0.15.0版的Pandas的腌制 pd.read_pickle 而不是 pickle.load 。看见 pickle docs

  • 在使用 PeriodIndex ,matplotlib内部轴现在将是 Period 而不是 PeriodIndex (这类似于如何使用 DatetimeIndex 传递的数组 datetimes 现在)

  • MultiIndexes will now raise similarly to other pandas objects w.r.t. truth testing, see here (GH7897).

  • 直接使用matplotlib的绘制DatetimeIndex时 plot 函数时,轴标签的格式将不再是日期,而是整数( datetime64 )。 UPDATE 这在0.15.1中已修复,请参见 here

不推荐使用#

  • 这些属性 Categorical labelslevels 属性已弃用,并已重命名为 codescategories

  • 这个 outtype 参数为 pd.DataFrame.to_dict 已被弃用,取而代之的是 orient 。 (GH7840 )

  • The convert_dummies method has been deprecated in favor of get_dummies (GH8140)

  • 这个 infer_dst 中的参数 tz_localize 将受到抨击,转而支持 ambiguous 以便在处理DST过渡时有更大的灵活性。替换 infer_dst=True 使用 ambiguous='infer' 对于相同的行为 (GH7943 )。看见 the docs 了解更多详细信息。

  • The top-level pd.value_range has been deprecated and can be replaced by .describe() (GH8481)

  • The Index set operations + and - were deprecated in order to provide these for numeric type operations on certain index types. + can be replaced by .union() or |, and - by .difference(). Further the method name Index.diff() is deprecated and can be replaced by Index.difference() (GH8226)

    # +
    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() 现在不起作用,已弃用 (GH7762GH7032 )。

删除先前版本的弃用/更改#

  • 删除 DataFrame.delevel 赞成的方法 DataFrame.reset_index

增强#

在导入/导出STATA文件方面的增强:

  • Added support for bool, uint8, uint16 and uint32 data types in to_stata (GH7097, GH7365)

  • 添加了导入Stata文件时的转换选项 (GH8527 )

  • DataFrame.to_stataStataWriter 检查字符串长度是否符合DTA文件中施加的限制,其中固定宽度的字符串必须包含244个或更少的字符。尝试写入字符串长度超过244个字符的Stata DTA文件会引发 ValueError 。 (GH7858 )

  • read_stataStataReader 可以将丢失的数据信息导入到 DataFrame 通过设置参数 convert_missingTrue 。使用此选项时,缺少的值返回为 StataMissingValue 包含缺失值的对象和列具有 object 数据类型。 (GH8045 )

绘图功能的增强:

  • 已添加 layout 关键字至 DataFrame.plot 。可以传递一个元组 (rows, columns) ,其中之一可以是 -1 自动推断 (GH6667GH8071 )。

  • Allow to pass multiple axes to DataFrame.plot, hist and boxplot (GH5353, GH6970, GH7069)

  • Added support for c, colormap and colorbar arguments for DataFrame.plot with kind='scatter' (GH7780)

  • Histogram from DataFrame.plot with kind='hist' (GH7809), See the docs.

  • Boxplot from DataFrame.plot with kind='box' (GH7998), See the docs.

其他:

  • read_csv now has a keyword parameter float_precision which specifies which floating-point converter the C engine should use during parsing, see here (GH8002, GH8044)

  • 已添加 searchsorted 方法来执行以下操作 Series 对象 (GH7447 )

  • describe() on mixed-types DataFrames is more flexible. Type-based column filtering is now possible via the include/exclude arguments. See the docs (GH8164).

    In [95]: df = pd.DataFrame({'catA': ['foo', 'foo', 'bar'] * 8,
       ....:                    'catB': ['a', 'b', 'c', 'd'] * 6,
       ....:                    'numC': np.arange(24),
       ....:                    'numD': np.arange(24.) + .5})
       ....: 
    
    In [96]: df.describe(include=["object"])
    Out[96]: 
           catA catB
    count    24   24
    unique    2    4
    top     foo    a
    freq     16    6
    
    [4 rows x 2 columns]
    
    In [97]: df.describe(include=["number", "object"], exclude=["float"])
    Out[97]: 
           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 [98]: df.describe(include='all')
    Out[98]: 
           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 将像以前一样运行,仅包括数字列,或者如果没有数字列,则仅包括分类列。另请参阅 docs

  • 已添加 split 作为对 orient 中的参数 pd.DataFrame.to_dict 。 (GH7840 )

  • 这个 get_dummies 方法现在可以在DataFrames上使用。默认情况下,只有分类列被编码为0和1,而其他列保持不变。

    In [99]: df = pd.DataFrame({'A': ['a', 'b', 'a'], 'B': ['c', 'c', 'b'],
       ....:                 'C': [1, 2, 3]})
       ....: 
    
    In [100]: pd.get_dummies(df)
    Out[100]: 
       C  A_a  A_b  B_b  B_c
    0  1    1    0    0    1
    1  2    0    1    0    1
    2  3    1    0    1    0
    
    [3 rows x 5 columns]
    
  • PeriodIndex supports resolution as the same as DatetimeIndex (GH7708)

  • pandas.tseries.holiday 增加了对额外节假日和节假日庆祝方式的支持 (GH7070 )

  • pandas.tseries.holiday.Holiday 现在支持Python3中的偏移量列表 (GH7070 )

  • pandas.tseries.holiday.Holiday 现在支持Days_of_Week参数 (GH7070 )

  • GroupBy.nth() 现在支持选择多个第n个值 (GH7910 )

    In [101]: business_dates = pd.date_range(start='4/1/2014', end='6/30/2014', freq='B')
    
    In [102]: df = pd.DataFrame(1, index=business_dates, columns=['a', 'b'])
    
    # get the first, 4th, and last date index for each month
    In [103]: df.groupby([df.index.year, df.index.month]).nth([0, 3, -1])
    Out[103]: 
            a  b
    2014 4  1  1
         4  1  1
         4  1  1
         5  1  1
         5  1  1
         5  1  1
         6  1  1
         6  1  1
         6  1  1
    
    [9 rows x 2 columns]
    
  • PeriodPeriodIndex 支持加/减 timedelta -点赞 (GH7966 )

    如果 Period 频率为 DHTSLUNTimedelta -如果结果可以有相同的频率,可以添加Like。否则,只有相同的 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 关键字现在可以识别 openpyxl1openpyxl2 其将显式地分别需要OpenPYX1V1和V2,如果所请求的版本不可用则失败。这个 openpyxl Engine现在是一个元引擎,可以自动使用任何已安装的Openpyxl版本。 (GH7177 )

  • DataFrame.fillna 现在可以接受 DataFrame 作为填充值 (GH8377 )

  • 将多个级别传递到 stack() 现在将在传递多个级别编号时起作用 (GH7660 )。看见 Reshaping by stacking and unstacking

  • set_names(), set_labels(), and set_levels() methods now take an optional level keyword argument to all modification of specific level(s) of a MultiIndex. Additionally set_names() now accepts a scalar string value when operating on an Index or on a specific level of a MultiIndex (GH7792)

    In [111]: idx = pd.MultiIndex.from_product([['a'], range(3), list("pqr")],
       .....:                                  names=['foo', 'bar', 'baz'])
       .....: 
    
    In [112]: idx.set_names('qux', level=0)
    Out[112]: 
    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 [113]: idx.set_names(['qux', 'corge'], level=[0, 1])
    Out[113]: 
    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 [114]: idx.set_levels(['a', 'b', 'c'], level='bar')
    Out[114]: 
    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 [115]: idx.set_levels([['a', 'b', 'c'], [1, 2, 3]], level=[1, 2])
    Out[115]: 
    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 参数指定用于成员资格测试的索引级别 (GH7892GH7890 )

    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 现在支持 duplicateddrop_duplicates 。 (GH4060 )

    In [116]: idx = pd.Index([1, 2, 3, 4, 1, 2])
    
    In [117]: idx
    Out[117]: Int64Index([1, 2, 3, 4, 1, 2], dtype='int64')
    
    In [118]: idx.duplicated()
    Out[118]: array([False, False, False, False,  True,  True])
    
    In [119]: idx.drop_duplicates()
    Out[119]: Int64Index([1, 2, 3, 4], dtype='int64')
    
  • 添加 copy=True 参数为 pd.concat 要启用完整数据块的传递,请执行以下操作 (GH8252 )

  • 添加了对NumPy 1.8+数据类型的支持 (bool_int_float_string_ )用于转换为R数据帧 (GH8400 )

性能#

  • 在以下方面的性能改进 DatetimeIndex.__iter__ 以实现更快的迭代 (GH7683 )

  • 在以下方面的性能改进 Period 创建(和 PeriodIndex 情况)) (GH5155 )

  • 改进Series.Transform以实现显著的性能提升(修订) (GH6496 )

  • 在以下方面的性能改进 StataReader 读取大文件时 (GH8040GH8073 )

  • 在以下方面的性能改进 StataWriter 在写入大文件时 (GH8079 )

  • Performance and memory usage improvements in multi-key groupby (GH8128)

  • Groupby中的性能改进 .agg.apply 其中,内置最大/最小值未映射到NumPy/Cythonated版本 (GH7722 )

  • 写入SQL时的性能改进 (to_sql )高达50% (GH8208 )。

  • 针对大值n组的Groupby进行性能基准测试 (GH6787 )

  • Performance improvement in CustomBusinessDay, CustomBusinessMonth (GH8236)

  • 性能提升 MultiIndex.values 对于包含日期时间的多级索引 (GH8543 )

错误修复#

  • 使用页边距和字典聚合函数时,PIVOT_TABLE中存在错误 (GH8349 )

  • 窃听 read_csv 哪里 squeeze=True 将返回一个视图 (GH8217 )

  • 检查中的表名时出现错误 read_sql 在某些情况下 (GH7826 )。

  • 窃听 DataFrame.groupby 哪里 Grouper 指定频率时不识别电平 (GH7885 )

  • 将DataFrame保存到SQL表时混合多索引数据类型的错误 (GH8021 )

  • 窃听 Series 0-带浮点和整数操作数数据类型的除法 (GH7785 )

  • 窃听 Series.astype("unicode") 没有来电 unicode 正确认识价值观 (GH7758 )

  • 窃听 DataFrame.as_matrix() 混合使用 datetime64[ns]timedelta64[ns] 数据类型 (GH7778 )

  • Bug in HDFStore.select_column() not preserving UTC timezone info when selecting a DatetimeIndex (GH7777)

  • 窃听 to_datetime 什么时候 format='%Y%m%d'coerce=True 之前返回对象数组的位置(而不是使用 NaT ), (GH7930 )

  • 窃听 DatetimeIndexPeriodIndex 就地加法和就地减法产生不同于正常结果的结果 (GH6527 )

  • Bug in adding and subtracting PeriodIndex with PeriodIndex raise TypeError (GH7741)

  • Bug in combine_first with PeriodIndex data raises TypeError (GH3367)

  • 缺少索引器的多索引切片中的错误 (GH7866 )

  • 具有各种边缘情况的多索引切片中的错误 (GH8132 )

  • 非标量类型对象的多索引索引中的回归 (GH7914 )

  • 窃听 Timestamp==int64 数据类型 (GH8058 )

  • 泡菜中的臭虫包含 DateOffset 可能会提高 AttributeError 什么时候 normalize 属性在内部引用 (GH7748 )

  • 窃听 Panel 在使用时 major_xscopy=False 已传递(由于缺少,弃用警告失败 warnings ) (GH8152 )。

  • Pickle反序列化中的错误,对于0.14.1之前的容器,带有DUP项的容器在匹配块和管理器项时试图避免歧义,当只有一个块时不会有歧义 (GH7794 )

  • Bug in putting a PeriodIndex into a Series would convert to int64 dtype, rather than object of Periods (GH7932)

  • 窃听 HDFStore 传递WHERE时的迭代 (GH8014 )

  • 窃听 DataFrameGroupby.transform 使用传递的未排序键进行转换时 (GH8046GH8430 )

  • 重复绘制时间序列线和面积图中的错误可能会导致 ValueError 或错误的种类 (GH7733 )

  • 中的推理错误 MultiIndex 使用 datetime.date 输入 (GH7888 )

  • 窃听 get 其中一个 IndexError 不会导致返回缺省值 (GH7725 )

  • 窃听 offsets.applyrollforwardrollback 可能重置为纳秒级 (GH7697 )

  • 窃听 offsets.applyrollforwardrollback 可能会提高 AttributeError 如果 Timestampdateutil TZINFO (GH7697 )

  • Bug in sorting a MultiIndex frame with a Float64Index (GH8017)

  • RHS为A的不一致面板组件中的错误 DataFrame 用于对齐 (GH7763 )

  • Bug in is_superperiod and is_subperiod cannot handle higher frequencies than S (GH7760, GH7772, GH7803)

  • Bug in 32-bit platforms with Series.shift (GH8129)

  • Bug in PeriodIndex.unique returns int64 np.ndarray (GH7540)

  • 窃听 groupby.apply 在该函数中有一个非影响突变 (GH8467 )

  • Bug in DataFrame.reset_index which has MultiIndex contains PeriodIndex or DatetimeIndex with tz raises ValueError (GH7746, GH7793)

  • 窃听 DataFrame.plot 使用 subplots=True 可能会绘制不必要的次要xtick和ytick (GH7801 )

  • 窃听 StataReader 由于Stata文档和实施之间的差异,无法读取117个文件中的变量标签 (GH7816 )

  • 窃听 StataReader 其中字符串始终转换为244个字符-固定宽度,与基础字符串大小无关 (GH7858 )

  • 窃听 DataFrame.plotSeries.plot 可能会忽略 rotfontsize 关键词 (GH7844 )

  • 窃听 DatetimeIndex.value_counts 不保留TZ (GH7735 )

  • Bug in PeriodIndex.value_counts results in Int64Index (GH7735)

  • 窃听 DataFrame.join 在索引上执行左联接并且有多个匹配项时 (GH5391 )

  • 窃听 GroupBy.transform() 其中,转换不保留索引的整型组被错误截断 (GH7972 )。

  • Bug in groupby where callable objects without name attributes would take the wrong path, and produce a DataFrame instead of a Series (GH7929)

  • 窃听 groupby DataFrame分组列重复时的错误消息 (GH7511 )

  • 窃听 read_html 其中 infer_types 争辩强迫不正确的约会点赞 (GH7762GH7032 )。

  • 窃听 Series.str.cat 具有经过筛选以不包括第一项的索引 (GH7857 )

  • 窃听 Timestamp 无法解析 nanosecond 发件人字符串 (GH7878 )

  • 窃听 Timestamp 使用字符串偏移量和 tz 结果不正确 (GH7833 )

  • 窃听 tslib.tz_converttslib.tz_convert_single 可能会返回不同的结果 (GH7798 )

  • Bug in DatetimeIndex.intersection of non-overlapping timestamps with tz raises IndexError (GH7880)

  • 与TimeOps和非唯一索引保持一致的错误 (GH8363 )

  • 窃听 GroupBy.filter() 其中,快速路径与慢速路径使筛选器返回一个看起来有效但实际上无效的非标量值 (GH7870 )。

  • 窃听 date_range()/DatetimeIndex() 从输入日期推断时区,但在跨越DST边界时返回错误的时间 (GH7835GH7901 )。

  • 窃听 to_excel() 其中负号被前置为正无穷大,而不是负无穷大 (GH7949 )

  • Bug in area plot draws legend with incorrect alpha when stacked=True (GH8027)

  • PeriodPeriodIndex 加法/减法 np.timedelta64 导致不正确的内部表示 (GH7740 )

  • 窃听 Holiday 没有偏移量或遵守 (GH7987 )

  • Bug in DataFrame.to_latex formatting when columns or index is a MultiIndex (GH7982).

  • 窃听 DateOffset 夏令时前后产生意想不到的结果 (GH5175 )。

  • 窃听 DataFrame.shift 空列将抛出的 ZeroDivisionError 关于NumPy 1.7 (GH8019 )

  • 在以下位置安装时出现错误 html_encoding/*.html 未安装,因此某些测试未正确运行 (GH7927 )。

  • Bug in read_html where bytes objects were not tested for in _read (GH7927).

  • 窃听 DataFrame.stack() 当其中一个列级别是类似日期的 (GH8039 )

  • Bug in broadcasting numpy scalars with DataFrame (GH8116)

  • Bug in pivot_table performed with nameless index and columns raises KeyError (GH8103)

  • 窃听 DataFrame.plot(kind='scatter') 指定颜色时,使用不同的颜色绘制点和错误条 c 关键字 (GH8081 )

  • 窃听 Float64Index 哪里 iatat 我们没有进行测试,而且失败了 (GH8092 )。

  • 窃听 DataFrame.boxplot() 在生成多个轴时未正确设置y限制的位置 (GH7528GH5517 )。

  • Bug in read_csv where line comments were not handled correctly given a custom line terminator or delim_whitespace=True (GH8122).

  • Bug in read_html where empty tables caused a StopIteration (GH7575)

  • 在相同数据类型的块中设置列时出现强制转换错误 (GH7704 )

  • 从访问组时出现错误 GroupBy 当原始石斑鱼是元组时 (GH8121 )。

  • 窃听 .at 它将接受非整数索引上的整数索引器并进行回退 (GH7814 )

  • KDE绘图和NAS中的错误 (GH8182 )

  • 窃听 GroupBy.count 不排除WITH FLOAT32数据类型为NaN值 (GH8169 )。

  • 带有堆叠的Barploy和Nan的BUG (GH8175 )。

  • 具有不可均匀分割偏移量的重新采样中的错误(例如‘7s’) (GH8371 )

  • 的插补方法中的错误 limit 不需要内插值时的关键字 (GH7173 )。

  • Bug where col_space was ignored in DataFrame.to_string() when header=False (GH8230).

  • BUG与 DatetimeIndex.asof 不正确匹配部分字符串并返回错误的日期 (GH8245 )。

  • 修改全局matplotlib rcParams的绘图方法中存在错误 (GH8242 )。

  • 窃听 DataFrame.__setitem__ 这导致在将DataFrame列设置为稀疏数组时出错 (GH8131 )

  • BUG在哪里 Dataframe.boxplot() 整列为空时失败 (GH8181 )。

  • 中的混乱变量错误 radviz 可视化 (GH8199 )。

  • 的插补方法中的错误 limit 不需要内插值时的关键字 (GH7173 )。

  • Bug where col_space was ignored in DataFrame.to_string() when header=False (GH8230).

  • 窃听 to_clipboard 这将剪裁长列数据 (GH8305 )

  • 窃听 DataFrame 端子显示:将max_Column/max_row设置为零不会触发自动调整DFS大小以适应端子宽度/高度 (GH7180 )。

  • OLS中的错误,使用“CLUSTER”和“NW_LAGS”参数运行时不能正常工作,但也不会抛出错误 (GH5884 )。

  • 窃听 DataFrame.dropna 将子集参数中不存在的列解释为“最后一列” (GH8303 )

  • 窃听 Index.intersection 关于非单调非唯一索引 (GH8362 )。

  • 掩码序列赋值中的错误,其中不匹配的类型会破坏对齐 (GH8387 )

  • 窃听 NDFrame.equals 给出带有dtype=Object的假阴性 (GH8437 )

  • 索引器的赋值错误,其中类型多样性会破坏对齐 (GH8258 )

  • 窃听 NDFrame.loc 当目标为列表时行/列名丢失时进行索引/ndarray (GH6552 )

  • 回归到 NDFrame.loc 如果目标是空列表,则行/列转换为Float64Index时进行索引/ndarray (GH7774 )

  • 窃听 Series 这使得它可以通过 DataFrame 这产生了意想不到的结果。不再允许这样的索引 (GH8444 )

  • 的项分配中存在错误 DataFrame 对于右侧列未对齐的多索引列 (GH7655 )

  • 在比较包含NaN的对象数组是否相等时,禁止NumPy生成的FutureWarning (GH7065 )

  • 窃听 DataFrame.eval() 其中,的数据类型 not 操作员 (~ )未被正确推断为 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 +