版本 0.21.0 (2017年10月27日)#
这是从 0.20.3 版本以来的一个主要发行版,包含多项 API 变更、弃用、新功能、改进和性能提升,以及大量的错误修复。我们建议所有用户升级到此版本。
主要亮点包括
与 Apache Parquet 集成,包括一个新的顶层
read_parquet()函数和DataFrame.to_parquet()方法,详见 此处。新的面向用户的
pandas.api.types.CategoricalDtype,用于独立于数据指定分类类型,详见 此处。在全 NaN Series/DataFrame 上调用
sum和prod的行为现在一致,并且不再依赖于是否安装了 bottleneck;以及在空 Series 上调用sum和prod现在返回 NaN 而不是 0,详见 此处。PyPy 的兼容性修复,详见 此处。
对
drop、reindex和renameAPI 的补充,使其更加一致,详见 此处。新增方法
DataFrame.infer_objects(详见 此处) 和GroupBy.pipe(详见 此处)。使用包含一个或多个缺失标签的标签列表进行索引已被弃用,并将在未来版本中引发 KeyError,详见 此处。
v0.21.0 中的新特性
新功能#
与 Apache Parquet 文件格式集成#
与 Apache Parquet 集成,包括一个新的顶层 read_parquet() 和 DataFrame.to_parquet() 方法,详见 此处 (GH 15838, GH 17438)。
Apache Parquet 提供了一种跨语言的二进制文件格式,用于高效地读写数据帧。Parquet 旨在忠实地序列化和反序列化 DataFrame,支持所有 pandas 数据类型,包括带时区的 datetime 等扩展数据类型。
此功能依赖于 pyarrow 或 fastparquet 库。更多详情,请参阅 Parquet 的 IO 文档。
方法 infer_objects 类型转换#
已新增 DataFrame.infer_objects() 和 Series.infer_objects() 方法,用于对对象列执行 dtype 推断,取代了已弃用的 convert_objects 方法的部分功能。更多详情,请参阅此处的文档。 (GH 11221)
此方法仅对对象列执行软转换,将 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]
方法 rename、reindex 现在也接受 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
140277028225232 1 4
140277028225264 2 5
140277028225296 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
140277028225232 1 4
140277028225264 2 5
140277028225296 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 并扩展,以包含 categories 和 ordered 属性。一个 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')
这些值已被正确解释为整数。
Categorical、CategoricalIndex 或分类类型 Series 的 .dtype 属性现在将返回 CategoricalDtype 的实例。虽然表示(repr)已更改,但 str(CategoricalDtype()) 仍然是字符串 'category'。我们在此提醒用户,检测分类数据首选的方式是使用 pandas.api.types.is_categorical_dtype(),而不是 str(dtype) == 'category'。
更多详情,请参阅CategoricalDtype 文档。
GroupBy 对象现在拥有 pipe 方法#
GroupBy 对象现在拥有 pipe 方法,类似于 DataFrame 和 Series 上的方法,允许以清晰、可读的语法组合接受 GroupBy 的函数。 (GH 17871)
关于结合 .groupby 和 .pipe 的具体示例,假设有一个 DataFrame,包含商店、产品、收入和销售数量的列。我们希望按商店和产品进行分组计算价格(即收入/数量)。我们可以通过多步操作完成此任务,但使用管道(piping)来表达可以使代码更具可读性。
首先我们设置数据
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 接受类字典参数#
rename_categories() 现在接受一个类字典参数作为 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_categories 将 Series 视为类列表。通常,Series 被认为是类字典(例如在 .rename、.map 中)。在未来的 pandas 版本中,rename_categories 将改为将它们视为类字典。请遵循警告消息的建议,编写面向未来的代码。
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]
其他改进#
新函数或方法#
Resampler.nearest()已添加,以支持最近邻上采样 (GH 17496)。
新关键词#
为
infer_dtype()添加了skipna参数,以支持在存在缺失值时进行类型推断 (GH 17059)。Series.to_dict()和DataFrame.to_dict()现在支持into关键词,允许您指定希望返回的collections.Mapping子类。默认值为dict,这是向后兼容的。 (GH 16122)Series.set_axis()和DataFrame.set_axis()现在支持inplace参数。 (GH 14636)Series.to_pickle()和DataFrame.to_pickle()新增了protocol参数 (GH 16252)。默认情况下,此参数设置为 HIGHEST_PROTOCOLread_feather()新增了nthreads参数,用于多线程操作 (GH 16359)DataFrame.clip()和Series.clip()新增了inplace参数。 (GH 15388)crosstab()新增了margins_name参数,用于定义当margins=True时包含总计的行/列的名称。 (GH 15972)read_json()现在接受chunksize参数,该参数可在lines=True时使用。如果传入chunksize,read_json 现在返回一个迭代器,每次迭代读取chunksize行。 (GH 17048)read_json()和to_json()现在接受compression参数,允许它们透明地处理压缩文件。 (GH 17798)
各项改进#
将 pandas 的导入时间提高了约 2.25 倍。 (GH 16764)
在大多数读取器(例如
read_csv())和写入器(例如DataFrame.to_csv())上支持 PEP 519 – 添加文件系统路径协议 (GH 13823)。为
pd.HDFStore、pd.ExcelFile和pd.ExcelWriter添加了__fspath__方法,以便正确支持文件系统路径协议 (GH 13823)。merge()的validate参数现在会检查合并是否为一对一、一对多、多对一或多对多。如果发现合并不属于指定合并类型,将引发MergeError类型的异常。更多详情,请参阅此处 (GH 16270)RangeIndex.append()现在在可能的情况下返回一个RangeIndex对象 (GH 16212)当
inplace=True时,Series.rename_axis()和DataFrame.rename_axis()在原地重命名轴时现在返回None。 (GH 15704)api.types.infer_dtype()现在可以推断小数。 (GH 15690)DataFrame.select_dtypes()现在接受标量值以及类列表值作为 include/exclude 参数。 (GH 16855)date_range()现在除了‘AS’之外,还接受‘YS’作为年初的别名。 (GH 9313)date_range()现在除了‘A’之外,还接受‘Y’作为年末的别名。 (GH 9313)DataFrame.add_prefix()和DataFrame.add_suffix()现在接受包含‘%’字符的字符串。 (GH 17151)能够推断压缩格式的读/写方法(
read_csv()、read_table()、read_pickle()和to_pickle())现在可以从类路径对象(例如pathlib.Path)推断。 (GH 17206)read_sas()现在能够识别 SAS7BDAT 文件中更常用的大部分日期(datetime)格式。 (GH 15871)DataFrame.items()和Series.items()现在同时存在于 Python 2 和 3 中,并且在所有情况下都为惰性求值。 (GH 13918, GH 17213)pandas.io.formats.style.Styler.where()已实现,作为pandas.io.formats.style.Styler.applymap()的一个便利方法。 (GH 17474)MultiIndex.is_monotonic_decreasing()已实现。之前在所有情况下都返回False。 (GH 16554)如果未安装
xlrd,read_excel()现在会引发带有更好消息的ImportError。 (GH 17613)对于 Python 3.6+ 用户,
DataFrame.assign()将保留**kwargs的原始顺序,而不是对列名进行排序。 (GH 14207)Series.reindex(),DataFrame.reindex(),Index.get_indexer()现在支持tolerance的类列表参数。 (GH 17367)
向后不兼容的 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 的求和/乘积现在一致地为 NaN#
注意
此处描述的更改已部分恢复。更多详情,请参阅v0.22.0 新特性。
sum 和 prod 在全 NaN Series/DataFrame 上的行为不再依赖于是否安装了 bottleneck,并且在空 Series 上调用 sum 和 prod 的返回值已更改 (GH 9422, GH 15507)。
在空或全 NaN 的 Series 或 DataFrame 列上调用 sum 或 prod 将导致 NaN。详见文档。
In [33]: s = pd.Series([np.nan])
以前,在未安装 bottleneck 的情况下
In [2]: s.sum()
Out[2]: np.nan
以前,在安装了 bottleneck 的情况下
In [2]: s.sum()
Out[2]: 0.0
新行为,不考虑 bottleneck 的安装情况
In [34]: s.sum()
Out[34]: 0.0
请注意,这也会改变空 Series 的求和结果。以前,无论是否安装 bottleneck,这总是返回 0
In [1]: pd.Series([]).sum()
Out[1]: 0
但为了与全 NaN 情况保持一致,这也已更改为返回 NaN。
In [2]: pd.Series([]).sum()
Out[2]: 0
使用包含缺失标签的列表进行索引已被弃用#
以前,使用包含一个或多个缺失标签的标签列表进行选择总是会成功,并为缺失的标签返回 NaN。现在,这会显示一个 FutureWarning。未来这将引发 KeyError (GH 15747)。当使用包含至少 1 个缺失标签的标签列表时,此警告将在对 DataFrame 或 Series 使用 .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 为 int 或 float 的 Series 使用某些迭代方法时,您会收到一个 numpy 标量(例如 np.int64),而不是 Python int。问题 (GH 10904) 修复了 Series.tolist() 和 list(Series) 的此问题。此更改使得所有迭代方法保持一致,特别是对于 __iter__() 和 .map();请注意,这仅影响 int/float 数据类型。 (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() 的迭代结果进行装箱。
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
使用布尔索引进行索引#
以前,当将布尔型 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
此外,以前如果您有一个非数值型索引(例如字符串),那么布尔型 Index 将引发 KeyError。现在,这将视为一个布尔索引器。
旧行为
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 重采样#
在以前的 pandas 版本中,对由 PeriodIndex 索引的 Series/DataFrame 进行重采样在某些情况下会返回 DatetimeIndex (GH 12884)。现在,重采样到倍数频率会返回一个 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]')
上采样并调用 .ohlc() 以前返回一个 Series,基本上与调用 .asfreq() 相同。OHLC 上采样现在返回一个包含 open、high、low 和 close 列的 DataFrame (GH 13083)。这与下采样和 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() 现在会在项赋值出错或指定原地操作但表达式中没有项赋值时引发 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
这是一种非常冗长的方式来说明 numpy 数组不支持字符串项索引。通过此更改,错误消息现在是这样
In [3]: pd.eval("a = 1 + 2", target=arr, inplace=True)
...
ValueError: Cannot assign expression output to target
以前,即使没有项赋值,也可以原地(inplace)评估表达式。
In [4]: pd.eval("1 + 2", target=arr, inplace=True)
Out[4]: 3
然而,这种输入意义不大,因为输出未被赋值给目标。现在,当传入此类输入时,将引发 ValueError。
In [4]: pd.eval("1 + 2", target=arr, inplace=True)
...
ValueError: Cannot operate inplace if there is no assignment
数据类型转换#
以前,带有 bool 赋值的赋值操作、.where() 和 .fillna() 会强制转换为相同的类型(例如 int / float),或者对日期时间类型引发错误。现在,这些操作将保留布尔值,并将其 dtype 设置为 object。 (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
以前,将非日期时间类型赋值给日期时间类型时,会被强制转换 (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
单层 MultiIndex 构造函数#
MultiIndex 构造函数不再将所有长度为一的 MultiIndex 压缩为常规 Index。这会影响所有的 MultiIndex 构造函数。 (GH 17178)
旧行为
In [2]: pd.MultiIndex.from_tuples([('a',), ('b',)])
Out[2]: Index(['a', 'b'], dtype='object')
长度为 1 的层不再作为特殊情况处理。它们的行为与长度为 2+ 的层完全相同,因此所有 MultiIndex 构造函数都将始终返回 MultiIndex。
In [54]: pd.MultiIndex.from_tuples([('a',), ('b',)])
Out[54]:
MultiIndex([('a',),
('b',)],
)
Series 的 UTC 本地化#
以前,当传递 utc=True 时,to_datetime() 不会对日期时间 Series 数据进行本地化。现在,to_datetime() 将正确地将具有 datetime64[ns, UTC] dtype 的 Series 本地化,以与类列表和 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() 解析的带有日期时间列的 DataFrame 也将仅在原始 SQL 列是时区感知日期时间列时才本地化为 UTC。
范围函数的一致性#
在以前的版本中,各种范围函数之间存在一些不一致性:date_range()、bdate_range()、period_range()、timedelta_range() 和 interval_range()。 (GH 17471)。
当同时指定 start、end 和 period 参数时,可能导致范围模糊,这是不一致行为之一。当传递所有三个参数时,interval_range 会忽略 period 参数,period_range 会忽略 end 参数,而其他范围函数则会引发错误。为了提高范围函数之间的一致性并避免潜在的模糊范围,当传递所有三个参数时,interval_range 和 period_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
此外,interval_range 生成的区间不包含端点参数 end。然而,所有其他范围函数都在其输出中包含 end。为了促进范围函数之间的一致性,interval_range 现在将把 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 在导入时不再自动注册我们针对 matplotlib 的 date、time、datetime、datetime64 和 Period 转换器。Matplotlib 绘图方法(plt.plot, ax.plot, …)将不会为 DatetimeIndex 或 PeriodIndex 值提供漂亮的 X 轴格式。您必须显式注册这些方法
pandas 内置的 Series.plot 和 DataFrame.plot 将在首次使用时注册这些转换器 (GH 17710)。
注意
此更改已在 pandas 0.21.1 中暂时恢复,更多详情请参阅此处。
其他 API 变更#
Categorical 构造函数不再接受标量作为
categories关键词。 (GH 16022)在已关闭的
HDFStore上访问不存在的属性现在将引发AttributeError,而不是ClosedFileError(GH 16301)read_csv()现在会在names参数包含重复项时发出UserWarning(GH 17095)read_csv()现在默认将字符串'null'和'n/a'视为空值 (GH 16471, GH 16078)pandas.HDFStore的字符串表示现在更快,且细节更少。如需之前的行为,请使用pandas.HDFStore.info()。(GH 16503)。HDF 存储中的压缩默认值现在遵循 pytables 标准。默认不压缩,如果缺少
complib且complevel> 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()在与objectdtypes 一起使用时,现在将引发TypeError,而不是ValueError(GH 13595)Period现在是不可变的,当用户尝试为ordinal或freq属性赋值时,将引发AttributeError(GH 17116)。当
to_datetime()传入时区感知的origin=关键字参数时,现在将引发更具信息量的ValueError,而不是TypeError(GH 16842)to_datetime()现在在格式包含%W或%U但没有同时包含星期几和日历年份时,会引发ValueError(GH 16774)为提高 API 一致性,已将
read_stata()中非功能的index重命名为index_col(GH 16342)DataFrame.drop()中的一个错误导致在从数字索引中删除索引时,布尔标签False和True分别被视为标签 0 和 1。现在这将引发ValueError(GH 16877)限制了 DateOffset 关键字参数。以前,
DateOffset子类允许任意关键字参数,这可能导致意外行为。现在,只接受有效参数。( GH 17176)。
弃用#
DataFrame.from_csv()和Series.from_csv()已被弃用,取而代之的是read_csv()(GH 4191)read_excel()已弃用sheetname,取而代之的是sheet_name,以与.to_excel()保持一致 (GH 10559)。read_excel()已弃用parse_cols,取而代之的是usecols,以与read_csv()保持一致 (GH 4988)read_csv()已弃用tupleize_cols参数。列元组将始终转换为MultiIndex(GH 17060)DataFrame.to_csv()已弃用tupleize_cols参数。MultiIndex 列将始终以行形式写入 CSV 文件 (GH 17060)在
.take()方法中,convert参数已被弃用,因为它未被遵守 (GH 16948)pd.options.html.border已弃用,取而代之的是pd.options.display.html.border(GH 15793)。SeriesGroupBy.nth()已弃用True,取而代之的是'all'作为其 kwargdropna的值 (GH 11038)。DataFrame.as_blocks()已弃用,因为它暴露了内部实现 (GH 17302)pd.TimeGrouper已弃用,取而代之的是pandas.Grouper(GH 16747)cdate_range已弃用,取而代之的是bdate_range(),后者增加了weekmask和holidays参数,用于构建自定义频率日期范围。详情请参阅文档 (GH 17596)已弃用向
Series.astype()传递categories或ordered关键字参数,取而代之的是传递 CategoricalDtype (GH 17636)Series、DataFrame、Panel、SparseSeries和SparseDataFrame上的.get_value和.set_value已弃用,取而代之的是使用.iat[]或.at[]访问器 (GH 15269)在
.to_excel(..., columns=)中传入不存在的列已被弃用,将来会引发KeyError(GH 17295)Series.where()、Series.mask()、DataFrame.where()、DataFrame.mask()中的raise_on_error参数已弃用,取而代之的是errors=(GH 14968)使用
DataFrame.rename_axis()和Series.rename_axis()更改索引或列的标签现在已被弃用,取而代之的是使用.rename。rename_axis仍可用于更改索引或列的名称 (GH 17833)。
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 实现了 argmax 和 argmin。自 pandas 0.13.0 以来,argmax 一直是 pandas.Series.idxmax() 的别名,argmin 一直是 pandas.Series.idxmin() 的别名。它们返回最大值或最小值的标签,而不是位置。
我们已弃用 Series.argmax 和 Series.argmin 的当前行为。使用它们中的任何一个都将发出 FutureWarning。如果您想要最大值的标签,请使用 Series.idxmax()。如果您想要最大值的位置,请使用 Series.values.argmax()。最小值同理。在未来的版本中,Series.argmax 和 Series.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)。
性能改进#
改进了
SparseDataFrame实例化的性能 (GH 16773)通过不实体化值,改进了
set_categories()的性能 (GH 17508)Timestamp.microsecond不再在属性访问时重新计算 (GH 17331)改进了
CategoricalIndex对已是分类 dtype 的数据的性能 (GH 17513)通过使用
RangeIndex属性执行计算,改进了RangeIndex.min()和RangeIndex.max()的性能 (GH 17607)
文档更改#
Bug 修复#
转换#
在对 datetime-like 数据使用
int进行赋值时,可能错误地转换为 datetime-like 类型 (GH 14145)将
float64dtype 的np.ndarray赋值给int64数据时可能保留int64dtype 的错误 (GH 14001)修复了
IntervalIndex.is_non_overlapping_monotonic的返回类型,使其成为 Python 的bool,以与类似属性/方法保持一致。以前返回numpy.bool_。(GH 17237)IntervalIndex.is_non_overlapping_monotonic中的一个错误,当区间两端都封闭并在一个点重叠时 (GH 16560)Series.fillna()中的一个错误,当inplace=True且value是字典时,会返回 DataFrame (GH 16156)Timestamp.weekday_name中的一个错误,在本地化到时区时返回基于 UTC 的星期几名称 (GH 17354)Timestamp.replace中替换tzinfo遇到夏令时变更时的错误 (GH 15683)Timedelta构造和算术中的一个错误,该错误不会传播Overflow异常 (GH 17367)astype()中的一个错误,当传递扩展类型类(DatetimeTZDtype、CategoricalDtype)而不是实例时,会转换为 object dtype。现在,当传递类时会引发TypeError(GH 17780)。to_numeric()中的一个错误,其中当errors='coerce'时,元素并不总是强制转换为数字类型 (GH 17007, GH 17125)DataFrame和Series构造函数中的一个错误,其中range对象在 Windows 上被转换为int32dtype 而不是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的错误 (GH 16957)在空
CategoricalIndex上重新索引时的错误 (GH 16770)修复了
DataFrame.loc用于带对齐和时区感知DatetimeIndex的设置 (GH 16889)避免在使用较旧的 numpy 时,将 Index 或 Series 传递给
.iloc导致IndexError(GH 17193)允许在 Python 2 中将 Unicode 空字符串作为多级列中的占位符 (GH 17099)
.iloc在与就地加法或赋值以及MultiIndex上的 int 索引器一起使用时,导致读取和写入错误的索引的错误 (GH 17148).isin()中的一个错误,其中检查空Series对象的成员资格时会引发错误 (GH 16991)CategoricalIndex重新索引中的一个错误,其中包含重复项的指定索引未被遵守 (GH 17323)RangeIndex与负步长的交集错误 (GH 17296)IntervalIndex中的一个错误,其中对非重叠单调递减索引的包含右端点进行标量查找失败 (GH 16417, GH 17271)DataFrame.first_valid_index()和DataFrame.last_valid_index()在没有有效条目时的错误 (GH 17400)Series.rename()在使用可调用对象调用时,错误地更改了Series的名称,而不是Index的名称。(GH 17407)String.str_get()在使用负索引时引发IndexError而不是插入 NaNs 的错误。( GH 17704)
I/O#
read_hdf()读取fixed格式 HDFStore 中的时区感知索引时出现错误 (GH 17618)read_csv()中的一个错误,其中列没有被彻底去重 (GH 17060)read_csv()中的一个错误,其中指定的列名没有被彻底去重 (GH 17095)read_csv()中的一个错误,其中 header 参数的非整数值生成了无用/不相关的错误消息 (GH 16338)read_csv()中的一个错误,在某些条件下,异常处理中的内存管理问题会导致解释器段错误 (GH 14696, GH 16798)。read_csv()在调用时low_memory=False的一个错误,其中包含至少一个大于 2GB 的列的 CSV 文件会错误地引发MemoryError(GH 16798)。read_csv()中的一个错误,当使用单元素列表header调用时,会返回一个包含所有 NaN 值的DataFrame(GH 7757)DataFrame.to_csv()在 Python 3 中默认编码为“ascii”而不是“utf-8”的错误 (GH 17097)read_stata()中的一个错误,其中在使用迭代器时无法读取值标签 (GH 16923)read_stata()中的一个错误,其中索引未设置 (GH 16342)read_html()中的一个错误,其中在多线程运行时导入检查失败 (GH 16928)read_csv()中的一个错误,其中自动分隔符检测在遇到错误行时会抛出TypeError而不是正确的错误消息 (GH 13374)DataFrame.to_html()在notebook=True时的一个错误,其中带有命名索引或非 MultiIndex 索引的 DataFrame 分别具有列标签或行标签的不需要的水平或垂直对齐 (GH 16792)DataFrame.to_html()中的一个错误,其中没有对justify参数进行验证 (GH 17527)HDFStore.select()在读取包含 VLArray 的连续混合数据表时的错误 (GH 17021)to_json()中的一个错误,其中几种情况(包括带有不可打印符号的对象、深度递归的对象、过长的标签)导致段错误而不是引发适当的异常 (GH 14256)
绘图#
绘图方法中使用
secondary_y和fontsize时,未设置次轴字体大小的错误 (GH 12565)在 y 轴上绘制
timedelta和datetimedtypes 时的错误 (GH 16953)折线图在计算 x 轴限制时不再假设 x 数据是单调的,即使对于未排序的 x 数据,它们现在也显示完整的线条。(GH 11310, GH 11471)
对于 matplotlib 2.0.0 及更高版本,折线图的 x 轴限制计算交由 matplotlib 处理,以便应用其新的默认设置。(GH 15495)
Series.plot.bar或DataFrame.plot.bar与y不遵守用户传入的color时的错误 (GH 16822)导致
plotting.parallel_coordinates在使用随机颜色时重置随机种子的错误 (GH 17525)
GroupBy/resample/rolling#
DataFrame.resample(...).size()中的一个错误,其中空的DataFrame没有返回Series(GH 14962)infer_freq()中的一个错误,导致工作周期间有 2 天间隔的索引被错误地推断为商务日频率 (GH 16624).rolling(...).quantile()中的一个错误,它错误地使用了与Series.quantile()和DataFrame.quantile()不同的默认值 (GH 9413, GH 16211)groupby.transform()中的一个错误,它会将布尔 dtype 强制转换回浮点数 (GH 16875)Series.resample(...).apply()中的一个错误,其中空的Series修改了源索引,并且没有返回Series的名称 (GH 14313).rolling(...).apply(...)与带有DatetimeIndex的DataFrame、可转换为 timedelta 的window以及min_periods >= 1一起使用时的错误 (GH 15305)DataFrame.groupby中的一个错误,当键的数量等于 groupby 轴上的元素数量时,索引和列键未被正确识别 (GH 16859)groupby.nunique()与TimeGrouper一起使用时无法正确处理NaT的错误 (GH 17575)DataFrame.groupby中的一个错误,其中从MultiIndex中选择单个级别会意外地排序 (GH 17537)DataFrame.groupby中的一个错误,其中当使用Grouper对象覆盖歧义列名时,会引发虚假警告 (GH 17383)TimeGrouper在作为列表和标量传递时表现不同 (GH 17530)
稀疏#
SparseSeries在将字典作为数据传入时引发AttributeError的错误 (GH 16905)SparseDataFrame.fillna()未填充从 SciPy 稀疏矩阵实例化时的所有 NaNs 的错误 (GH 16112)SparseSeries.unstack()和SparseDataFrame.stack()中的错误 (GH 16614, GH 15045)make_sparse()中的一个错误,当数组dtype是object时,将具有相同位数的两个数字/布尔数据视为相同 (GH 17574)SparseArray.all()和SparseArray.any()现在已实现以处理SparseArray,这些已被使用但未实现 (GH 17570)
重塑#
使用非唯一
PeriodIndex进行连接/合并时引发TypeError(GH 16871)crosstab()中的一个错误,其中非对齐的整数 Series 被转换为浮点数 (GH 17005)与具有布尔/整数数据类型的分类 dtype 进行合并时,错误地引发
TypeError的错误 (GH 16900)在大型对象 Series 和大型比较数组上使用
isin()时的错误 (GH 16012)修复了 0.20 版本的回归,
Series.aggregate()和DataFrame.aggregate()再次允许字典作为返回值 (GH 16741)修复了当
pivot_table()在调用时margins=True时,整数 dtype 输入的结果 dtype (GH 17013)crosstab()中的一个错误,其中传递两个同名的Series会引发KeyError(GH 13279)Series.argmin()、Series.argmax()以及它们在DataFrame和 groupby 对象上的对应方法,可以正确处理包含无穷大值的浮点数据 (GH 13595)。修复了在具有
NaT值的datetime64dtypeSeries上按多列排序时的回归 (GH 16836)pivot_table()中的一个错误,当dropna为False时,结果的列未保留columns的分类 dtype (GH 17842)DataFrame.drop_duplicates中的一个错误,其中删除非唯一列名时引发ValueError(GH 17836)unstack()中的一个错误,当在级别列表上调用时,会丢弃fillna参数 (GH 13971)range对象和其他列表状对象与DataFrame对齐时的一个错误,导致操作按行而不是按列执行 (GH 17901)
数值#
.clip()在axis=1且传入threshold为列表状对象时的一个错误;以前这会引发ValueError(GH 15390)Series.clip()和DataFrame.clip()现在将上限和下限参数的 NA 值视为None,而不是引发ValueError(GH 17276)。
分类#
Series.isin()在使用分类数据调用时的错误 (GH 16639)使用空值和类别构建分类器时的一个错误,导致
.categories成为空的Float64Index而不是带有 object dtype 的空Index(GH 17248)分类操作中的一个错误,其中 Series.cat 未保留原始 Series 的名称 (GH 17509)
DataFrame.merge()合并布尔/整数数据类型的分类列时失败的错误 (GH 17187)在指定
categories为分类类型时,构造Categorical/CategoricalDtype的错误 (GH 17884)。
PyPy#
与 PyPy 在
read_csv()与usecols=[<unsorted ints>]和read_json()时的兼容性 (GH 17351)根据需要将测试拆分为 CPython 和 PyPy 的用例,这突出了索引匹配
float('nan')、np.nan和NAT时的脆弱性 (GH 17351)修复了
DataFrame.memory_usage()以支持 PyPy。PyPy 上的对象没有固定大小,因此改用近似值 (GH 17228)
其他#
贡献者#
共有 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 +