版本 0.21.0 (2017年10月27日)#

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

主要亮点包括

  • Apache Parquet 集成,包括新的顶级 read_parquet() 函数和 DataFrame.to_parquet() 方法,详见此处

  • 新的面向用户的 pandas.api.types.CategoricalDtype,用于独立于数据指定分类,详见此处

  • 在全为 NaN 的 Series/DataFrame 上执行 sumprod 的行为现已一致,不再取决于是否安装了 bottleneck,并且在空 Series 上执行 sumprod 现在返回 NaN 而不是 0,详见此处

  • 对 pypy 的兼容性修复,详见此处

  • 增加了 dropreindexrename API 以使其更一致,详见此处

  • 添加了新方法 DataFrame.infer_objects (详见此处) 和 GroupBy.pipe (详见此处)。

  • 使用包含一个或多个缺失标签的标签列表进行索引已被弃用,并在未来版本中将引发 KeyError,详见此处

更新前请检查API 更改弃用

新特性#

与 Apache Parquet 文件格式集成#

Apache Parquet 集成,包括新的顶级 read_parquet() 函数和 DataFrame.to_parquet() 方法,详见此处GH 15838, GH 17438)。

Apache Parquet 提供了一种跨语言、二进制文件格式,用于高效地读取和写入数据帧。Parquet 旨在精确序列化和反序列化 DataFrame,支持所有 pandas dtypes,包括带时区的 datetime 等扩展 dtypes。

此功能依赖于 pyarrowfastparquet 库。更多详情请参阅 IO 文档中关于 Parquet 的部分

infer_objects 方法类型转换#

添加了 DataFrame.infer_objects()Series.infer_objects() 方法,用于对 object 列执行 dtype 推断,取代了已弃用的 convert_objects 方法的部分功能。更多详情请参阅此处的文档。(GH 11221

此方法仅对 object 列执行软转换,将 Python 对象转换为原生类型,但不进行任何强制转换。例如

In [1]: df = pd.DataFrame({'A': [1, 2, 3],
   ...:                    'B': np.array([1, 2, 3], dtype='object'),
   ...:                    'C': ['1', '2', '3']})
   ...: 

In [2]: df.dtypes
Out[2]: 
A     int64
B    object
C    object
Length: 3, dtype: object

In [3]: df.infer_objects().dtypes
Out[3]: 
A     int64
B     int64
C    object
Length: 3, dtype: object

注意,列 'C' 未被转换 - 只有标量数值类型会被转换为新类型。其他类型的转换应使用 to_numeric() 函数(或 to_datetime(), to_timedelta())来完成。

In [4]: df = df.infer_objects()

In [5]: df['C'] = pd.to_numeric(df['C'], errors='coerce')

In [6]: df.dtypes
Out[6]: 
A    int64
B    int64
C    int64
Length: 3, dtype: object

创建列时改进了警告信息#

新用户经常对 DataFrame 实例上的列操作和属性访问之间的关系感到困惑(GH 7175)。这种困惑的一个具体例子是尝试通过在 DataFrame 上设置属性来创建新列

In [1]: df = pd.DataFrame({'one': [1., 2., 3.]})
In [2]: df.two = [4, 5, 6]

这不会引发任何明显的异常,但也不会创建新列

In [3]: df
Out[3]:
    one
0  1.0
1  2.0
2  3.0

现在将列表式数据结构赋值给新属性会引发 UserWarning,提示可能存在意外行为。详见属性访问

drop 方法现在也接受 index/columns 关键字#

drop() 方法新增了 index/columns 关键字作为指定 axis 的替代方法。这类似于 reindex 的行为(GH 12392)。

例如

In [7]: df = pd.DataFrame(np.arange(8).reshape(2, 4),
   ...:                   columns=['A', 'B', 'C', 'D'])
   ...: 

In [8]: df
Out[8]: 
   A  B  C  D
0  0  1  2  3
1  4  5  6  7

[2 rows x 4 columns]

In [9]: df.drop(['B', 'C'], axis=1)
Out[9]: 
   A  D
0  0  3
1  4  7

[2 rows x 2 columns]

# the following is now equivalent
In [10]: df.drop(columns=['B', 'C'])
Out[10]: 
   A  D
0  0  3
1  4  7

[2 rows x 2 columns]

renamereindex 方法现在也接受 axis 关键字#

DataFrame.rename()DataFrame.reindex() 方法新增了 axis 关键字,用于指定操作的目标轴(GH 12392)。

这是 rename

In [11]: df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})

In [12]: df.rename(str.lower, axis='columns')
Out[12]: 
   a  b
0  1  4
1  2  5
2  3  6

[3 rows x 2 columns]

In [13]: df.rename(id, axis='index')
Out[13]: 
                 A  B
140639502074064  1  4
140639502074096  2  5
140639502074128  3  6

[3 rows x 2 columns]

这是 reindex

In [14]: df.reindex(['A', 'B', 'C'], axis='columns')
Out[14]: 
   A  B   C
0  1  4 NaN
1  2  5 NaN
2  3  6 NaN

[3 rows x 3 columns]

In [15]: df.reindex([0, 1, 3], axis='index')
Out[15]: 
     A    B
0  1.0  4.0
1  2.0  5.0
3  NaN  NaN

[3 rows x 2 columns]

“index, columns” 风格的使用方式仍然有效。

In [16]: df.rename(index=id, columns=str.lower)
Out[16]: 
                 a  b
140639502074064  1  4
140639502074096  2  5
140639502074128  3  6

[3 rows x 2 columns]

In [17]: df.reindex(index=[0, 1, 3], columns=['A', 'B', 'C'])
Out[17]: 
     A    B   C
0  1.0  4.0 NaN
1  2.0  5.0 NaN
3  NaN  NaN NaN

[3 rows x 3 columns]

我们强烈建议在使用任何一种风格时使用命名参数,以避免混淆。

CategoricalDtype 用于指定分类#

pandas.api.types.CategoricalDtype 已添加到公共 API 并进行了扩展,包括 categoriesordered 属性。CategoricalDtype 可用于指定数组的类别集合和顺序性,独立于数据本身。这在将字符串数据转换为 Categorical 时非常有用(GH 14711, GH 15078, GH 16015, GH 17643)。

In [18]: from pandas.api.types import CategoricalDtype

In [19]: s = pd.Series(['a', 'b', 'c', 'a'])  # strings

In [20]: dtype = CategoricalDtype(categories=['a', 'b', 'c', 'd'], ordered=True)

In [21]: s.astype(dtype)
Out[21]: 
0    a
1    b
2    c
3    a
Length: 4, dtype: category
Categories (4, object): ['a' < 'b' < 'c' < 'd']

需要特别提及的一点是在 read_csv() 中。之前,使用 dtype={'col': 'category'} 时,返回的值和类别始终是字符串。

In [22]: data = 'A,B\na,1\nb,2\nc,3'

In [23]: pd.read_csv(StringIO(data), dtype={'B': 'category'}).B.cat.categories
Out[23]: Index(['1', '2', '3'], dtype='object')

请注意“object” dtype。

使用全部为数值、日期时间或时间差的 CategoricalDtype,我们可以自动转换为正确的类型

In [24]: dtype = {'B': CategoricalDtype([1, 2, 3])}

In [25]: pd.read_csv(StringIO(data), dtype=dtype).B.cat.categories
Out[25]: Index([1, 2, 3], dtype='int64')

这些值已被正确地解释为整数。

CategoricalCategoricalIndex 或具有分类类型的 Series.dtype 属性现在将返回一个 CategoricalDtype 实例。虽然 repr 发生了变化,但 str(CategoricalDtype()) 仍然是字符串 'category'。在此,我们提醒用户,检测分类数据的首选方式是使用 pandas.api.types.is_categorical_dtype(),而不是 str(dtype) == 'category'

更多详情请参阅 CategoricalDtype 文档

GroupBy 对象现在拥有一个 pipe 方法#

GroupBy 对象现在拥有一个 pipe 方法,类似于 DataFrameSeries 上的方法,它允许以简洁、可读的语法组合接受 GroupBy 的函数。(GH 17871

对于结合使用 .groupby.pipe 的具体示例,假设您有一个 DataFrame,包含商店、产品、收入和销售数量等列。我们希望按商店和产品进行分组计算价格(即收入/数量)。我们可以在多个步骤中完成此操作,但通过管道方式表达可以使代码更具可读性。

首先设置数据

In [26]: import numpy as np

In [27]: n = 1000

In [28]: df = pd.DataFrame({'Store': np.random.choice(['Store_1', 'Store_2'], n),
   ....:                    'Product': np.random.choice(['Product_1',
   ....:                                                 'Product_2',
   ....:                                                 'Product_3'
   ....:                                                 ], n),
   ....:                    'Revenue': (np.random.random(n) * 50 + 10).round(2),
   ....:                    'Quantity': np.random.randint(1, 10, size=n)})
   ....: 

In [29]: df.head(2)
Out[29]: 
     Store    Product  Revenue  Quantity
0  Store_2  Product_2    32.09         7
1  Store_1  Product_3    14.20         1

[2 rows x 4 columns]

现在,要查找按商店/产品计算的价格,我们可以简单地执行

In [30]: (df.groupby(['Store', 'Product'])
   ....:    .pipe(lambda grp: grp.Revenue.sum() / grp.Quantity.sum())
   ....:    .unstack().round(2))
   ....: 
Out[30]: 
Product  Product_1  Product_2  Product_3
Store                                   
Store_1       6.73       6.72       7.14
Store_2       7.59       6.98       7.23

[2 rows x 3 columns]

更多详情请参阅文档

Categorical.rename_categories 接受 dict-like 参数#

rename_categories() 现在接受 dict-like 参数用于 new_categories。先前的类别会在字典的键中查找,如果找到则替换。缺失键和多余键的行为与 DataFrame.rename() 中的行为相同。

In [31]: c = pd.Categorical(['a', 'a', 'b'])

In [32]: c.rename_categories({"a": "eh", "b": "bee"})
Out[32]: 
['eh', 'eh', 'bee']
Categories (2, object): ['eh', 'bee']

警告

为了帮助升级 pandas,rename_categoriesSeries 视为 list-like。通常,Series 被视为 dict-like(例如在 .rename, .map 中)。在未来版本的 pandas 中,rename_categories 将更改为将其视为 dict-like。请遵循警告消息中的建议来编写未来兼容的代码。

In [33]: c.rename_categories(pd.Series([0, 1], index=['a', 'c']))
FutureWarning: Treating Series 'new_categories' as a list-like and using the values.
In a future version, 'rename_categories' will treat Series like a dictionary.
For dict-like, use 'new_categories.to_dict()'
For list-like, use 'new_categories.values'.
Out[33]:
[0, 0, 1]
Categories (2, int64): [0, 1]

其他增强功能#

新函数或方法#

新关键字#

各种增强功能#

向后不兼容的 API 更改#

依赖项的最低版本已提高#

我们更新了依赖项的最低支持版本 (GH 15206, GH 15543, GH 15214)。如果已安装,我们现在要求

最低版本

必需

Numpy

1.9.0

X

Matplotlib

1.4.3

Scipy

0.14.0

Bottleneck

1.0.0

此外,已放弃对 Python 3.4 的支持 (GH 15251)。

全为 NaN 或空 Series/DataFrame 的 sum/prod 现在一致返回 NaN#

注意

此处描述的更改已被部分恢复。详情请参阅 v0.22.0 新内容

对全为 NaN 的 Series/DataFrames 调用 sumprod 的行为不再取决于是否安装了 bottleneck,并且对空 Series 调用 sumprod 的返回值已更改 (GH 9422, GH 15507)。

对空的或全为 NaNSeries,或 DataFrame 的列调用 sumprod,将导致 NaN。请参阅 文档

In [33]: s = pd.Series([np.nan])

之前 WITHOUT bottleneck installed (未安装 bottleneck 时)

In [2]: s.sum()
Out[2]: np.nan

之前 WITH bottleneck (已安装 bottleneck 时)

In [2]: s.sum()
Out[2]: 0.0

New behavior, without regard to the bottleneck installation (新行为,与 bottleneck 安装无关)

In [34]: s.sum()
Out[34]: 0.0

注意,这也会改变空 Seriessum 结果。之前,无论是否安装 bottleneck,这总是返回 0

In [1]: pd.Series([]).sum()
Out[1]: 0

但为了与全为 NaN 的情况保持一致,这也被更改为返回 0

In [2]: pd.Series([]).sum()
Out[2]: 0

使用包含缺失标签的列表进行索引已弃用#

之前,使用标签列表进行选择时,如果一个或多个标签缺失,操作总是会成功,并为缺失标签返回 NaN。现在将显示 FutureWarning。将来这将引发 KeyError (GH 15747)。当使用包含至少 1 个缺失标签的 list-of-labels (标签列表) 作为参数时,在使用 DataFrameSeries.loc[][[]] 时会触发此警告。

In [35]: s = pd.Series([1, 2, 3])

In [36]: s
Out[36]: 
0    1
1    2
2    3
Length: 3, dtype: int64

旧行为

In [4]: s.loc[[1, 2, 3]]
Out[4]:
1    2.0
2    3.0
3    NaN
dtype: float64

当前行为

In [4]: s.loc[[1, 2, 3]]
Passing list-likes to .loc or [] with any missing label will raise
KeyError in the future, you can use .reindex() as an alternative.

See the documentation here:
https://pandas.ac.cn/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike

Out[4]:
1    2.0
2    3.0
3    NaN
dtype: float64

实现选择可能找不到的元素的惯用方法是通过 .reindex()

In [37]: s.reindex([1, 2, 3])
Out[37]: 
1    2.0
2    3.0
3    NaN
Length: 3, dtype: float64

所有键都找到时的选择行为不变。

In [38]: s.loc[[1, 2]]
Out[38]: 
1    2
2    3
Length: 2, dtype: int64

NA 命名更改#

为了提高 pandas API 的一致性,我们添加了额外的顶级函数 isna()notna(),它们是 isnull()notnull() 的别名。现在的命名方案与 .dropna().fillna() 等方法更一致。此外,在定义了 .isnull().notnull() 方法的所有情况下,都增加了名为 .isna().notna() 的方法,这些方法包含在 Categorical, Index, Series, 和 DataFrame 类中。( GH 15001)。

配置选项 pd.options.mode.use_inf_as_null 已弃用,并添加了 pd.options.mode.use_inf_as_na 作为替代。

Series/Index 的迭代现在将返回 Python 标量#

之前,当对 dtype 为 intfloatSeries 使用某些迭代方法时,会收到一个 numpy 标量,例如 np.int64,而不是 Python int。Issue (GH 10904) 修复了 Series.tolist()list(Series) 的此问题。此更改使所有迭代方法保持一致,特别是对于 __iter__().map();请注意,这仅影响 int/float dtypes。( GH 13236, GH 13258, GH 14216)。

In [39]: s = pd.Series([1, 2, 3])

In [40]: s
Out[40]: 
0    1
1    2
2    3
Length: 3, dtype: int64

之前

In [2]: type(list(s)[0])
Out[2]: numpy.int64

新行为

In [41]: type(list(s)[0])
Out[41]: int

此外,现在 DataFrame.to_dict() 的迭代结果也将被正确地 box (装箱)。

In [42]: d = {'a': [1], 'b': ['b']}

In [43]: df = pd.DataFrame(d)

之前

In [8]: type(df.to_dict()['a'][0])
Out[8]: numpy.int64

新行为

In [44]: type(df.to_dict()['a'][0])
Out[44]: int

使用布尔索引进行索引#

之前,将 boolean Index 传递给 .loc 时,如果 Series/DataFrame 的索引具有 boolean 标签,你会获得基于标签的选择(可能重复结果标签),而不是布尔索引选择(其中 True 选择元素),这与布尔 numpy 数组索引的方式不一致。新行为是像布尔 numpy 数组索引器一样操作。( GH 17738)

旧行为

In [45]: s = pd.Series([1, 2, 3], index=[False, True, False])

In [46]: s
Out[46]: 
False    1
True     2
False    3
Length: 3, dtype: int64
In [59]: s.loc[pd.Index([True, False, True])]
Out[59]:
True     2
False    1
False    3
True     2
dtype: int64

当前行为

In [47]: s.loc[pd.Index([True, False, True])]
Out[47]: 
False    1
False    3
Length: 2, dtype: int64

此外,之前如果索引是非数值类型(例如字符串),则 boolean Index 会引发 KeyError。现在这将作为布尔索引器处理。

Previously behavior (旧行为)

In [48]: s = pd.Series([1, 2, 3], index=['a', 'b', 'c'])

In [49]: s
Out[49]: 
a    1
b    2
c    3
Length: 3, dtype: int64
In [39]: s.loc[pd.Index([True, False, True])]
KeyError: "None of [Index([True, False, True], dtype='object')] are in the [index]"

当前行为

In [50]: s.loc[pd.Index([True, False, True])]
Out[50]: 
a    1
c    3
Length: 2, dtype: int64

PeriodIndex 重采样#

在 previous versions (旧版本) 中,对 PeriodIndex 索引的 Series/DataFrame 进行重采样有时会返回 DatetimeIndex (GH 12884)。现在重采样到 multiplied frequency (倍频程) 会返回 PeriodIndex (GH 15944)。作为一项小改进,PeriodIndex 的重采样现在可以处理 NaT 值 (GH 13224)

旧行为

In [1]: pi = pd.period_range('2017-01', periods=12, freq='M')

In [2]: s = pd.Series(np.arange(12), index=pi)

In [3]: resampled = s.resample('2Q').mean()

In [4]: resampled
Out[4]:
2017-03-31     1.0
2017-09-30     5.5
2018-03-31    10.0
Freq: 2Q-DEC, dtype: float64

In [5]: resampled.index
Out[5]: DatetimeIndex(['2017-03-31', '2017-09-30', '2018-03-31'], dtype='datetime64[ns]', freq='2Q-DEC')

新行为

In [1]: pi = pd.period_range('2017-01', periods=12, freq='M')

In [2]: s = pd.Series(np.arange(12), index=pi)

In [3]: resampled = s.resample('2Q').mean()

In [4]: resampled
Out[4]:
2017Q1    2.5
2017Q3    8.5
Freq: 2Q-DEC, dtype: float64

In [5]: resampled.index
Out[5]: PeriodIndex(['2017Q1', '2017Q3'], dtype='period[2Q-DEC]')

之前,upsampling (向上采样) 并调用 .ohlc() 会返回一个 Series,与调用 .asfreq() 基本相同。现在 OHLC 向上采样会返回一个 DataFrame,其列为 open, high, lowclose (GH 13083)。这与 downsampling (向下采样) 和 DatetimeIndex 的行为一致。

旧行为

In [1]: pi = pd.period_range(start='2000-01-01', freq='D', periods=10)

In [2]: s = pd.Series(np.arange(10), index=pi)

In [3]: s.resample('H').ohlc()
Out[3]:
2000-01-01 00:00    0.0
                ...
2000-01-10 23:00    NaN
Freq: H, Length: 240, dtype: float64

In [4]: s.resample('M').ohlc()
Out[4]:
         open  high  low  close
2000-01     0     9    0      9

新行为

In [56]: pi = pd.period_range(start='2000-01-01', freq='D', periods=10)

In [57]: s = pd.Series(np.arange(10), index=pi)

In [58]: s.resample('H').ohlc()
Out[58]:
                  open  high  low  close
2000-01-01 00:00   0.0   0.0  0.0    0.0
2000-01-01 01:00   NaN   NaN  NaN    NaN
2000-01-01 02:00   NaN   NaN  NaN    NaN
2000-01-01 03:00   NaN   NaN  NaN    NaN
2000-01-01 04:00   NaN   NaN  NaN    NaN
...                ...   ...  ...    ...
2000-01-10 19:00   NaN   NaN  NaN    NaN
2000-01-10 20:00   NaN   NaN  NaN    NaN
2000-01-10 21:00   NaN   NaN  NaN    NaN
2000-01-10 22:00   NaN   NaN  NaN    NaN
2000-01-10 23:00   NaN   NaN  NaN    NaN

[240 rows x 4 columns]

In [59]: s.resample('M').ohlc()
Out[59]:
         open  high  low  close
2000-01     0     9    0      9

[1 rows x 4 columns]

改进了 pd.eval 中进行元素赋值时的错误处理#

eval() 现在在 item assignment (元素赋值) malfunctions (故障),或者指定了 inplace operations (原地操作) 但表达式中没有元素赋值时,会引发 ValueError (GH 16732)

In [51]: arr = np.array([1, 2, 3])

之前,如果你尝试以下表达式,你会得到一个不太有用的错误消息

In [3]: pd.eval("a = 1 + 2", target=arr, inplace=True)
...
IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`)
and integer or boolean arrays are valid indices

This is a very long way of saying numpy arrays don’t support string-item indexing. With this change, the error message is now this (这是一种非常冗长的方式来解释 numpy 数组不支持字符串元素索引。通过此更改,错误消息现在是这样)

In [3]: pd.eval("a = 1 + 2", target=arr, inplace=True)
...
ValueError: Cannot assign expression output to target

It also used to be possible to evaluate expressions inplace (原地评估),即使没有 item assignment (元素赋值)

In [4]: pd.eval("1 + 2", target=arr, inplace=True)
Out[4]: 3

然而,这种输入没有多大意义,因为输出没有被赋值给 target (目标)。现在,当传入 such an input (这样的输入) 时,将引发 ValueError

In [4]: pd.eval("1 + 2", target=arr, inplace=True)
...
ValueError: Cannot operate inplace if there is no assignment

Dtype 转换#

之前,assignments (赋值)、.where().fillna() 使用 bool assignment (布尔赋值) 时,会强制转换为相同的 type (类型)(例如 int / float),或者对 datetimelikes (类日期时间类型) 引发错误。现在这些操作将保留 bool 值,并使用 object dtypes。( GH 16821)。

In [52]: s = pd.Series([1, 2, 3])
In [5]: s[1] = True

In [6]: s
Out[6]:
0    1
1    1
2    3
dtype: int64

新行为

In [7]: s[1] = True

In [8]: s
Out[8]:
0       1
1    True
2       3
Length: 3, dtype: object

之前,将 non-datetimelike (非类日期时间类型) 赋值给 datetimelike (类日期时间类型) 会强制转换被赋值的非类日期时间项 (GH 14145)。

In [53]: s = pd.Series([pd.Timestamp('2011-01-01'), pd.Timestamp('2012-01-01')])
In [1]: s[1] = 1

In [2]: s
Out[2]:
0   2011-01-01 00:00:00.000000000
1   1970-01-01 00:00:00.000000001
dtype: datetime64[ns]

现在这些操作会强制转换为 object dtype。

In [1]: s[1] = 1

In [2]: s
Out[2]:
0    2011-01-01 00:00:00
1                      1
dtype: object
  • .where() 对 datetimelikes (类日期时间类型) 的行为不一致,会引发错误而不是强制转换为 object (GH 16402)

  • 使用 np.ndarray 且 dtype 为 float64int64 数据进行 assignment (赋值) 时可能保持 int64 dtype 的 bug (GH 14001)

单层 MultiIndex 构造函数#

MultiIndex 构造函数不再将所有 length-one levels (长度为一的层) 的 MultiIndex 压缩成常规的 Index。这影响所有 MultiIndex 构造函数。( GH 17178)

旧行为

In [2]: pd.MultiIndex.from_tuples([('a',), ('b',)])
Out[2]: Index(['a', 'b'], dtype='object')

Length 1 levels (长度为 1 的层) 不再进行特殊处理。它们 behave exactly as if you had length 2+ levels (行为与长度为 2+ 的层完全相同),所以所有 MultiIndex 构造函数总是返回一个 MultiIndex

In [54]: pd.MultiIndex.from_tuples([('a',), ('b',)])
Out[54]: 
MultiIndex([('a',),
            ('b',)],
           )

使用 Series 进行 UTC 本地化#

之前,to_datetime() 在传入 utc=True 时不会对 datetime Series 数据进行本地化。现在,to_datetime() 将正确地对具有 datetime64[ns, UTC] dtype 的 Series 进行本地化,以便与 list-like (列表式) 和 Index 数据的处理方式保持一致。( GH 6415)。

旧行为

In [55]: s = pd.Series(['20130101 00:00:00'] * 3)
In [12]: pd.to_datetime(s, utc=True)
Out[12]:
0   2013-01-01
1   2013-01-01
2   2013-01-01
dtype: datetime64[ns]

新行为

In [56]: pd.to_datetime(s, utc=True)
Out[56]: 
0   2013-01-01 00:00:00+00:00
1   2013-01-01 00:00:00+00:00
2   2013-01-01 00:00:00+00:00
Length: 3, dtype: datetime64[ns, UTC]

此外,被 read_sql_table()read_sql_query() 解析的包含 datetime 列的 DataFrames 也将仅在 original SQL columns (原始 SQL 列) 是 timezone aware datetime columns (时区感知的 datetime 列) 时,localize to UTC (本地化到 UTC)。

range 函数的一致性#

在 previous versions (旧版本) 中,various range functions (各种 range 函数) 之间存在一些 inconsistencies (不一致):date_range(), bdate_range(), period_range(), timedelta_range(), 和 interval_range()。( GH 17471)。

其中一个 inconsistent behaviors (不一致的行为) 发生在同时指定 start, endperiod 参数时,potentially leading to ambiguous ranges (可能导致模糊的范围)。当传入所有三个参数时,interval_range 忽略 period 参数,period_range 忽略 end 参数,而其他 range 函数则引发错误。为了 promote consistency (促进一致性) 并在 range 函数之间,并 avoid potentially ambiguous ranges (避免潜在的模糊范围),现在当同时传入这三个参数时,interval_rangeperiod_range 将引发错误。

旧行为

 In [2]: pd.interval_range(start=0, end=4, periods=6)
 Out[2]:
 IntervalIndex([(0, 1], (1, 2], (2, 3]]
               closed='right',
               dtype='interval[int64]')

In [3]: pd.period_range(start='2017Q1', end='2017Q4', periods=6, freq='Q')
Out[3]: PeriodIndex(['2017Q1', '2017Q2', '2017Q3', '2017Q4', '2018Q1', '2018Q2'], dtype='period[Q-DEC]', freq='Q-DEC')

新行为

In [2]: pd.interval_range(start=0, end=4, periods=6)
---------------------------------------------------------------------------
ValueError: Of the three parameters: start, end, and periods, exactly two must be specified

In [3]: pd.period_range(start='2017Q1', end='2017Q4', periods=6, freq='Q')
---------------------------------------------------------------------------
ValueError: Of the three parameters: start, end, and periods, exactly two must be specified

此外,endpoint parameter (端点参数) end previously was not included in the intervals produced by interval_range (之前 interval_range 生成的区间不包含)。然而,所有 other range functions (其他 range 函数) include end in their output (输出都包含 end)。为了 promote consistency (促进一致性) among the range functions,现在 interval_range 将 include end as the right endpoint of the final interval (包含 end 作为最后一个区间的右端点),except if freq is specified in a way which skips end (除非 freq 的指定方式跳过了 end)。

旧行为

In [4]: pd.interval_range(start=0, end=4)
Out[4]:
IntervalIndex([(0, 1], (1, 2], (2, 3]]
              closed='right',
              dtype='interval[int64]')

新行为

In [57]: pd.interval_range(start=0, end=4)
Out[57]: IntervalIndex([(0, 1], (1, 2], (2, 3], (3, 4]], dtype='interval[int64, right]')

无自动 Matplotlib 转换器#

导入 pandas 时,pandas 不再向 matplotlib 注册我们的 date, time, datetime, datetime64, 和 Period 转换器。Matplotlib plot methods (绘图方法) (plt.plot, ax.plot, …) 将不会 nicely format (很好地格式化) DatetimeIndexPeriodIndex 值的 x-axis (x 轴)。你必须 explicitly register (显式注册)这些 methods (方法)

pandas built-in (内置的) Series.plotDataFrame.plot will register (将注册) 这些 converters (转换器) on first-use (首次使用时) (GH 17710)。

注意

此更改已在 pandas 0.21.1 中 temporarily reverted (暂时恢复),for more details see here (详情请参阅这里)。

其他 API 更改#

  • The Categorical constructor (构造函数) no longer accepts a scalar (不再接受标量) for the categories keyword。( GH 16022)

  • Accessing a non-existent attribute (访问不存在的属性) on a closed HDFStore will now raise an AttributeError rather than a ClosedFileError (GH 16301)

  • read_csv() 现在 issues a UserWarning (发出 UserWarning) if the names parameter contains duplicates (参数包含重复项) (GH 17095)

  • read_csv() 现在默认将字符串 'null''n/a' 视为缺失值 (GH 16471, GH 16078)

  • pandas.HDFStore 的字符串表示形式现在更快,细节更少。要恢复以前的行为,请使用 pandas.HDFStore.info()。 (GH 16503)。

  • HDF 存储中的压缩默认设置现在遵循 pytables 标准。默认不进行压缩,如果缺少 complibcomplevel > 0,则使用 zlib (GH 15943)

  • Index.get_indexer_non_unique() 现在返回一个 ndarray 索引器而不是一个 Index;这与 Index.get_indexer() 保持一致 (GH 16819)

  • pandas._testing 中移除了 @slow 装饰器,该装饰器导致了一些下游软件包的测试套件出现问题。请改用 @pytest.mark.slow,这能实现同样的效果 (GH 16850)

  • MergeError 的定义移到了 pandas.errors 模块。

  • Series.set_axis()DataFrame.set_axis() 的签名已从 set_axis(axis, labels) 更改为 set_axis(labels, axis=0),以便与 API 的其余部分保持一致。旧的签名已被弃用,并将显示 FutureWarning (GH 14636)

  • Series.argmin()Series.argmax() 现在在使用 object dtype 时会引发 TypeError,而不是 ValueError (GH 13595)

  • Period 现在是不可变的,当用户尝试为 ordinalfreq 属性分配新值时,将引发 AttributeError (GH 17116)。

  • to_datetime() 在传入时区感知的 origin= kwarg 时,现在会引发更具信息的 ValueError,而不是 TypeError (GH 16842)

  • to_datetime() 现在在格式包含 %W%U 但没有同时包含星期几和日历年份时会引发 ValueError (GH 16774)

  • read_stata() 中将不工作的 index 重命名为 index_col,以提高 API 的一致性 (GH 16342)

  • DataFrame.drop() 中的一个错误导致在从数字索引中删除索引时,布尔标签 FalseTrue 分别被视为标签 0 和 1。现在这将引发 ValueError (GH 16877)

  • 限制了 DateOffset 的关键字参数。以前,DateOffset 子类允许任意关键字参数,这可能导致意外行为。现在,只接受有效的参数。 (GH 17176)。

弃用#

Series.select 和 DataFrame.select#

Series.select()DataFrame.select() 方法已被弃用,请改用 df.loc[labels.map(crit)] (GH 12401)

In [58]: df = pd.DataFrame({'A': [1, 2, 3]}, index=['foo', 'bar', 'baz'])
In [3]: df.select(lambda x: x in ['bar', 'baz'])
FutureWarning: select is deprecated and will be removed in a future release. You can use .loc[crit] as a replacement
Out[3]:
     A
bar  2
baz  3
In [59]: df.loc[df.index.map(lambda x: x in ['bar', 'baz'])]
Out[59]: 
     A
bar  2
baz  3

[2 rows x 1 columns]

Series.argmax 和 Series.argmin#

Series.argmax()Series.argmin() 的行为已被弃用,请分别改用 Series.idxmax()Series.idxmin() (GH 16830)。

为了与 NumPy 数组兼容,pd.Series 实现了 argmaxargmin。自 pandas 0.13.0 起,argmaxpandas.Series.idxmax() 的别名,argminpandas.Series.idxmin() 的别名。它们返回最大值或最小值的*标签*,而不是*位置*。

我们已弃用 Series.argmaxSeries.argmin 的当前行为。使用其中任何一个都将发出 FutureWarning。如果要获取最大值的标签,请使用 Series.idxmax()。如果要获取最大值的位置,请使用 Series.values.argmax()。最小值同理。在未来的版本中,Series.argmaxSeries.argmin 将返回最大值或最小值的位置。

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

  • read_excel() 已移除 has_index_names 参数 (GH 10967)

  • pd.options.display.height 配置已被移除 (GH 3663)

  • pd.options.display.line_width 配置已被移除 (GH 2881)

  • pd.options.display.mpl_style 配置已被移除 (GH 12190)

  • Index 已移除 .sym_diff() 方法,请改用 .symmetric_difference() (GH 12591)

  • Categorical 已移除 .order().sort() 方法,请改用 .sort_values() (GH 12882)

  • eval()DataFrame.eval() 已将 inplace 的默认值从 None 更改为 False (GH 11149)

  • 函数 get_offset_name 已被移除,请改用偏移量的 .freqstr 属性 (GH 11834)

  • pandas 不再测试与使用 pandas < 0.11 创建的 hdf5 文件的兼容性 (GH 17404)。

性能改进#

文档更改#

Bug 修复#

转换#

  • int 对日期时间类数据进行赋值时存在一个 bug,可能错误地转换为日期时间类 (GH 14145)

  • 使用 np.ndarray 且 dtype 为 float64int64 数据进行 assignment (赋值) 时可能保持 int64 dtype 的 bug (GH 14001)

  • 修复了 IntervalIndex.is_non_overlapping_monotonic 的返回类型,使其成为 Python 的 bool,以便与类似的属性/方法保持一致。之前返回的是 numpy.bool_。 (GH 17237)

  • 当区间两端都封闭并在某个点重叠时,IntervalIndex.is_non_overlapping_monotonic 中存在一个 bug (GH 16560)

  • inplace=Truevalue 为 dict 时,Series.fillna() 返回 frame 的 bug (GH 16156)

  • 当本地化到时区时,Timestamp.weekday_name 返回基于 UTC 的星期几名称的 bug (GH 17354)

  • Timestamp.replace 在 DST 更改附近替换 tzinfo 时存在一个 bug (GH 15683)

  • Timedelta 构造和算术运算中存在一个 bug,它不会传播 Overflow 异常 (GH 17367)

  • astype() 在传入扩展类型类(DatetimeTZDtypeCategoricalDtype)而不是实例时转换为 object dtype 的 bug。现在,当传入类时会引发 TypeError (GH 17780)。

  • to_numeric() 中存在一个 bug,当 errors='coerce' 时,元素并非总是被强制转换为数字类型 (GH 17007, GH 17125)

  • DataFrameSeries 构造函数中存在一个 bug,即 range 对象在 Windows 上被转换为 int32 dtype 而不是 int64 (GH 16804)

索引#

  • 当使用空切片(例如 df.iloc[:])调用时,.iloc.loc 索引器返回原始对象的浅拷贝。以前它们返回原始对象。 (GH 13873)。

  • 当在未排序的 MultiIndex 上调用时,loc 索引器现在仅在使用适当的切片处理非排序级别时才会引发 UnsortedIndexError (GH 16734)。

  • 修复了在 0.20.3 中使用字符串对 TimedeltaIndex 进行索引时的回归问题 (GH 16896)。

  • 修复了 TimedeltaIndex.get_loc()np.timedelta64 输入的处理 (GH 16909)。

  • 修复了 MultiIndex.sort_index()ascending 参数是列表但并非所有级别都已指定或顺序不同时的排序问题 (GH 16934)。

  • 修复了使用 np.inf 进行索引导致引发 OverflowError 的 bug (GH 16957)

  • 在空的 CategoricalIndex 上进行 reindexing 时存在的 bug (GH 16770)

  • 修复了使用对齐和时区感知的 DatetimeIndex 进行设置时的 DataFrame.loc (GH 16889)

  • 使用较旧的 numpy 时,将 IndexSeries 传递给 .iloc 时避免 IndexError (GH 17193)

  • 允许在 Python 2 的多级列中使用 unicode 空字符串作为占位符 (GH 17099)

  • .iloc 在与就地加法或赋值一起使用,并在 MultiIndex 上使用 int 索引器时存在的 bug,导致从错误索引读取和写入 (GH 17148)

  • .isin() 中检查空 Series 对象成员关系时引发错误的 bug (GH 16991)

  • CategoricalIndex reindexing 中未遵守包含重复项的指定索引的 bug (GH 17323)

  • RangeIndex 与负步长求交集时存在的 bug (GH 17296)

  • IntervalIndex 中执行标量查找在非重叠单调递减索引的包含右端点时失败的 bug (GH 16417, GH 17271)

  • DataFrame.first_valid_index()DataFrame.last_valid_index() 在没有有效条目时存在的 bug (GH 17400)

  • Series.rename() 在使用可调用对象调用时,错误地更改了 Series 的名称,而不是 Index 的名称。 (GH 17407)

  • String.str_get() 在使用负索引时引发 IndexError 而不是插入 NaNs 的 bug。 (GH 17704)

IO#

  • read_hdf() 在从 fixed 格式的 HDFStore 读取时区感知索引时存在的 bug (GH 17618)

  • read_csv() 中列未被彻底去重的 bug (GH 17060)

  • read_csv() 中的一个 Bug,指定列名未被彻底去重 (GH 17095)

  • read_csv() 中的一个 Bug,header 参数使用非整数值时会生成无用/不相关的错误消息 (GH 16338)

  • read_csv() 中的一个 Bug,在某些条件下,异常处理中的内存管理问题会导致解释器崩溃 (segfault) (GH 14696, GH 16798)。

  • read_csv() 在调用时设置 low_memory=False 的一个 Bug,如果 CSV 中至少有一列大于 2GB,会错误地引发 MemoryError (GH 16798)。

  • read_csv() 在调用时设置 header 为单元素列表的一个 Bug,会返回一个所有值为 NaN 的 DataFrame (GH 7757)

  • Python 3 中 DataFrame.to_csv() 默认使用 'ascii' 编码而不是 'utf-8' 的一个 Bug (GH 17097)

  • read_stata() 中的一个 Bug,使用迭代器时无法读取值标签 (GH 16923)

  • read_stata() 中的一个 Bug,索引未被设置 (GH 16342)

  • read_html() 中的一个 Bug,在多线程中运行时导入检查失败 (GH 16928)

  • read_csv() 中的一个 Bug,自动定界符检测在遇到错误行时会抛出 TypeError 而不是正确的错误消息 (GH 13374)

  • DataFrame.to_html() 在设置 notebook=True 时的 Bug,具有命名索引或非 MultiIndex 索引的 DataFrame 在列或行标签上分别出现不希望的水平或垂直对齐 (GH 16792)

  • DataFrame.to_html() 中的一个 Bug,未对 justify 参数进行验证 (GH 17527)

  • HDFStore.select() 在读取包含 VLArray 的连续混合数据表时的 Bug (GH 17021)

  • to_json() 中的一个 Bug,在几种条件下(包括包含不可打印符号的对象、深度递归对象、过长标签)会导致崩溃 (segfault) 而不是引发相应的异常 (GH 14256)

绘图#

  • 绘图方法使用 secondary_yfontsize 时未设置次坐标轴字体大小的 Bug (GH 12565)

  • 在 y 轴上绘制 timedeltadatetime 数据类型时的 Bug (GH 16953)

  • 折线图在计算 x 轴范围 (xlims) 时不再假定 x 数据是单调的,即使 x 数据未排序,现在也会显示完整的线条。 (GH 11310, GH 11471)

  • 对于 Matplotlib 2.0.0 及更高版本,折线图的 x 轴范围计算交由 Matplotlib 处理,以便应用其新的默认设置。 (GH 15495)

  • Series.plot.barDataFrame.plot.bar 中,设置 y 参数时未遵循用户传入的 color 参数的 Bug (GH 16822)

  • plotting.parallel_coordinates 在使用随机颜色时导致随机种子重置的 Bug (GH 17525)

分组/重采样/滚动计算#

  • DataFrame.resample(...).size() 中的一个 Bug,空 DataFrame 未返回 Series (GH 14962)

  • infer_freq() 中的一个 Bug,导致工作周内有 2 天间隔的索引被错误地推断为工作日频率 (GH 16624)

  • .rolling(...).quantile() 中的一个 Bug,错误地使用了与 Series.quantile()DataFrame.quantile() 不同的默认值 (GH 9413, GH 16211)

  • groupby.transform() 中的一个 Bug,会将布尔数据类型强制转换回浮点类型 (GH 16875)

  • Series.resample(...).apply() 中的一个 Bug,空 Series 修改了源索引且未返回 Series 的名称 (GH 14313)

  • .rolling(...).apply(...) 中的一个 Bug,当 DataFrame 具有 DatetimeIndexwindow 参数可转换为 timedelta 且 min_periods >= 1 时发生 (GH 15305)

  • DataFrame.groupby 中的一个 Bug,当键的数量等于 groupby 轴上的元素数量时,索引和列键未被正确识别 (GH 16859)

  • groupby.nunique()TimeGrouper 一起使用时的 Bug,无法正确处理 NaT (GH 17575)

  • DataFrame.groupby 中的一个 Bug,从 MultiIndex 中选择单层时出现意外排序 (GH 17537)

  • DataFrame.groupby 中的一个 Bug,当使用 Grouper 对象覆盖模糊的列名时会引发虚假警告 (GH 17383)

  • TimeGrouper 作为列表和作为标量传递时表现不同的 Bug (GH 17530)

稀疏数据#

  • SparseSeries 中的一个 Bug,当字典作为数据传入时会引发 AttributeError (GH 16905)

  • SparseDataFrame.fillna() 中的一个 Bug,当 frame 从 SciPy 稀疏矩阵实例化时未填充所有 NaN (GH 16112)

  • SparseSeries.unstack()SparseDataFrame.stack() 中的 Bug (GH 16614, GH 15045)

  • make_sparse() 中的一个 Bug,当数组 dtypeobject 时,将两个具有相同比特位的数字/布尔数据视为相同 (GH 17574)

  • SparseArray.all()SparseArray.any() 现在已实现以处理 SparseArray,这些方法之前被使用但未实现 (GH 17570)

重塑#

  • 与非唯一 PeriodIndex 进行连接/合并时引发 TypeError (GH 16871)

  • crosstab() 中的一个 Bug,未对齐的整数 Series 被转换为浮点数 (GH 17005)

  • 与分类数据类型和类似日期时间类型合并时错误地引发 TypeError 的 Bug (GH 16900)

  • 在大型对象 Series 和大型比较数组上使用 isin() 时的 Bug (GH 16012)

  • 修复了 0.20 版本的回归 Bug,Series.aggregate()DataFrame.aggregate() 再次允许字典作为返回值 (GH 16741)

  • 修复了使用整数数据类型输入时,调用 pivot_table() 并设置 margins=True 的结果数据类型问题 (GH 17013)

  • crosstab() 中的一个 Bug,传入两个同名的 Series 时引发 KeyError (GH 13279)

  • Series.argmin()Series.argmax() 以及它们在 DataFrame 和 groupby 对象上的对应方法,现在可以正确处理包含无穷大值的浮点数据。 (GH 13595)。

  • unique() 中的一个 Bug,检查字符串元组时引发 TypeError (GH 17108)

  • concat() 中的一个 Bug,如果结果索引包含不可比较的元素,其顺序将不可预测 (GH 17344)

  • 修复了对包含 NaT 值的 datetime64 数据类型 Series 按多列排序时的回归 Bug (GH 16836)

  • pivot_table() 中的一个 Bug,当 dropnaFalse 时,结果的列未保留 columns 参数的分类数据类型 (GH 17842)

  • DataFrame.drop_duplicates 中的一个 Bug,使用非唯一列名去重时引发 ValueError (GH 17836)

  • unstack() 中的一个 Bug,当对层级列表调用时会忽略 fillna 参数 (GH 13971)

  • range 对象和其他类似列表对象与 DataFrame 对齐时的 Bug,导致操作按行而不是按列执行 (GH 17901)

数值计算#

  • .clip() 中的一个 Bug,当 axis=1threshold 传入列表状对象时发生;之前会引发 ValueError (GH 15390)

  • Series.clip()DataFrame.clip() 现在将 upper 和 lower 参数的 NA 值视为 None,而不是引发 ValueError。 (GH 17276)。

分类数据#

  • Series.isin() 与分类数据一起调用时的 Bug (GH 16639)

  • 分类构造函数在值和类别为空时导致 .categories 成为空的 Float64Index 而不是空的 Index (object dtype) 的 Bug (GH 17248)

  • 使用 Series.cat 进行分类操作时未保留原始 Series 名称的 Bug (GH 17509)

  • DataFrame.merge() 对于布尔/整数数据类型的分类列合并失败的 Bug (GH 17187)

  • 构建 Categorical/CategoricalDtype 时,指定的 categories 已经是分类类型时的 Bug。 (GH 17884)。

PyPy#

  • read_csv()usecols=[<unsorted ints>] 条件下与 PyPy 的兼容性问题 以及 read_json() 与 PyPy 的兼容性问题 (GH 17351)

  • 在需要的地方将测试拆分为 CPython 和 PyPy 的不同情况,这凸显了使用 float('nan')np.nanNAT 进行索引匹配时的脆弱性 (GH 17351)

  • 修复了 DataFrame.memory_usage() 以支持 PyPy。PyPy 上的对象没有固定大小,因此使用了近似值。 (GH 17228)

其他#

  • 一些就地 (inplace) 操作符未被正确封装,调用时产生了副本的 Bug (GH 12962)

  • eval() 中的一个 Bug,inplace 参数被错误处理 (GH 16732)

贡献者#

共有 206 人为本次发布贡献了补丁。名字旁带有 “+” 的人是首次贡献补丁。

  • 3553x +

  • Aaron Barber

  • Adam Gleave +

  • Adam Smith +

  • AdamShamlian +

  • Adrian Liaw +

  • Alan Velasco +

  • Alan Yee +

  • Alex B +

  • Alex Lubbock +

  • Alex Marchenko +

  • Alex Rychyk +

  • Amol K +

  • Andreas Winkler

  • Andrew +

  • Andrew 亮

  • André Jonasson +

  • Becky Sweger

  • Berkay +

  • Bob Haffner +

  • Bran Yang

  • Brian Tu +

  • Brock Mendel +

  • Carol Willing +

  • Carter Green +

  • Chankey Pathak +

  • Chris

  • Chris Billington

  • Chris Filo Gorgolewski +

  • Chris Kerr

  • Chris M +

  • Chris Mazzullo +

  • Christian Prinoth

  • Christian Stade-Schuldt

  • Christoph Moehl +

  • DSM

  • Daniel Chen +

  • Daniel Grady

  • Daniel Himmelstein

  • Dave Willmer

  • David Cook

  • David Gwynne

  • David Read +

  • Dillon Niederhut +

  • Douglas Rudd

  • Eric Stein +

  • Eric Wieser +

  • Erik Fredriksen

  • Florian Wilhelm +

  • Floris Kint +

  • Forbidden Donut

  • Gabe F +

  • Giftlin +

  • Giftlin Rajaiah +

  • Giulio Pepe +

  • Guilherme Beltramini

  • Guillem Borrell +

  • Hanmin Qin +

  • Hendrik Makait +

  • Hugues Valois

  • Hussain Tamboli +

  • Iva Miholic +

  • Jan Novotný +

  • Jan Rudolph

  • Jean Helie +

  • Jean-Baptiste Schiratti +

  • Jean-Mathieu Deschenes

  • Jeff Knupp +

  • Jeff Reback

  • Jeff Tratner

  • JennaVergeynst

  • JimStearns206

  • Joel Nothman

  • John W. O’Brien

  • Jon Crall +

  • Jon Mease

  • Jonathan J. Helmus +

  • Joris Van den Bossche

  • JosephWagner

  • Juarez Bochi

  • Julian Kuhlmann +

  • Karel De Brabandere

  • Kassandra Keeton +

  • Keiron Pizzey +

  • Keith Webber

  • Kernc

  • Kevin Sheppard

  • Kirk Hansen +

  • Licht Takeuchi +

  • Lucas Kushner +

  • Mahdi Ben Jelloul +

  • Makarov Andrey +

  • Malgorzata Turzanska +

  • Marc Garcia +

  • Margaret Sy +

  • MarsGuy +

  • Matt Bark +

  • Matthew Roeschke

  • Matti Picus

  • Mehmet Ali “Mali” Akmanalp

  • Michael Gasvoda +

  • Michael Penkov +

  • Milo +

  • Morgan Stuart +

  • Morgan243 +

  • Nathan Ford +

  • Nick Eubank

  • Nick Garvey +

  • Oleg Shteynbuk +

  • P-Tillmann +

  • Pankaj Pandey

  • Patrick Luo

  • Patrick O’Melveny

  • Paul Reidy +

  • Paula +

  • Peter Quackenbush

  • Peter Yanovich +

  • Phillip Cloud

  • Pierre Haessig

  • Pietro Battiston

  • Pradyumna Reddy Chinthala

  • Prasanjit Prakash

  • RobinFiveWords

  • Ryan Hendrickson

  • Sam Foo

  • Sangwoong Yoon +

  • Simon Gibbons +

  • SimonBaron

  • Steven Cutting +

  • Sudeep +

  • Sylvia +

  • T N +

  • Telt

  • Thomas A Caswell

  • Tim Swast +

  • Tom Augspurger

  • Tong SHEN

  • Tuan +

  • Utkarsh Upadhyay +

  • Vincent La +

  • Vivek +

  • WANG Aiyong

  • WBare

  • Wes McKinney

  • XF +

  • Yi Liu +

  • Yosuke Nakabayashi +

  • aaron315 +

  • abarber4gh +

  • aernlund +

  • agustín méndez +

  • andymaheshw +

  • ante328 +

  • aviolov +

  • bpraggastis

  • cbertinato +

  • cclauss +

  • chernrick

  • chris-b1

  • dkamm +

  • dwkenefick

  • economy

  • faic +

  • fding253 +

  • gfyoung

  • guygoldberg +

  • hhuuggoo +

  • huashuai +

  • ian

  • iulia +

  • jaredsnyder

  • jbrockmendel +

  • jdeschenes

  • jebob +

  • jschendel +

  • keitakurita

  • kernc +

  • kiwirob +

  • kjford

  • linebp

  • lloydkirk

  • louispotok +

  • majiang +

  • manikbhandari +

  • margotphoenix +

  • matthiashuschle +

  • mattip

  • mjlove12 +

  • nmartensen +

  • pandas-docs-bot +

  • parchd-1 +

  • philipphanemann +

  • rdk1024 +

  • reidy-p +

  • ri938

  • ruiann +

  • rvernica +

  • s-weigand +

  • scotthavard92 +

  • skwbc +

  • step4me +

  • tobycheese +

  • topper-123 +

  • tsdlovell

  • ysau +

  • zzgao +