版本 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
和rename
API 的补充,使其更加一致,详见 此处。新增方法
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()
在与object
dtypes 一起使用时,现在将引发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)将
float64
dtype 的np.ndarray
赋值给int64
数据时可能保留int64
dtype 的错误 (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 上被转换为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
的错误 (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
和datetime
dtypes 时的错误 (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
值的datetime64
dtypeSeries
上按多列排序时的回归 (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 +