版本 0.19.0 (2016 年 10 月 2 日)#
这是 0.18.1 版本的一个主要更新,包含多项 API 变更、一些新特性、增强功能和性能改进,以及大量的 bug 修复。我们建议所有用户升级到此版本。
主要亮点包括
用于 asof 风格时间序列连接的
merge_asof()
,详见此处.rolling()
现在具备时间序列感知能力,详见此处read_csv()
现在支持解析Categorical
数据,详见此处新增了用于合并 Categorical 数据的函数
union_categorical()
,详见此处PeriodIndex
现在拥有自己的period
dtype,并且变得与其他Index
类更加一致。详见此处稀疏数据结构增强了对
int
和bool
dtypes 的支持,详见此处与
Series
的比较操作不再忽略索引,关于 API 变更的概述,详见此处。引入了用于实用函数的 pandas 开发 API,详见此处。
Panel4D
和PanelND
已弃用。我们建议使用 xarray 包来表示这类 n 维数据。移除了先前已弃用的模块
pandas.io.data
、pandas.io.wb
、pandas.tools.rplot
。
警告
pandas >= 0.19.0 在导入时不再静默处理 numpy ufunc 警告,详见此处。
v0.19.0 版本的新特性
新特性#
用于 asof 风格时间序列连接的函数 merge_asof
#
通过函数 merge_asof()
添加了一个长期以来被请求的功能,以支持 asof 风格的时间序列连接(GH 1870, GH 13695, GH 13709, GH 13902)。完整文档请参阅此处。
merge_asof()
执行 asof 合并,这类似于左连接,但不是基于相等键匹配,而是基于最近键匹配。
In [1]: left = pd.DataFrame({"a": [1, 5, 10], "left_val": ["a", "b", "c"]})
In [2]: right = pd.DataFrame({"a": [1, 2, 3, 6, 7], "right_val": [1, 2, 3, 6, 7]})
In [3]: left
Out[3]:
a left_val
0 1 a
1 5 b
2 10 c
[3 rows x 2 columns]
In [4]: right
Out[4]:
a right_val
0 1 1
1 2 2
2 3 3
3 6 6
4 7 7
[5 rows x 2 columns]
通常,我们希望尽可能精确匹配,否则使用最近的值。
In [5]: pd.merge_asof(left, right, on="a")
Out[5]:
a left_val right_val
0 1 a 1
1 5 b 3
2 10 c 7
[3 rows x 3 columns]
我们也可以只匹配先行数据(prior data),而不是精确匹配。
In [6]: pd.merge_asof(left, right, on="a", allow_exact_matches=False)
Out[6]:
a left_val right_val
0 1 a NaN
1 5 b 3.0
2 10 c 7.0
[3 rows x 3 columns]
在典型的时间序列示例中,我们有 trades
和 quotes
,我们想对它们进行 asof-join
。这也说明了如何使用 by
参数在合并前对数据进行分组。
In [7]: trades = pd.DataFrame(
...: {
...: "time": pd.to_datetime(
...: [
...: "20160525 13:30:00.023",
...: "20160525 13:30:00.038",
...: "20160525 13:30:00.048",
...: "20160525 13:30:00.048",
...: "20160525 13:30:00.048",
...: ]
...: ),
...: "ticker": ["MSFT", "MSFT", "GOOG", "GOOG", "AAPL"],
...: "price": [51.95, 51.95, 720.77, 720.92, 98.00],
...: "quantity": [75, 155, 100, 100, 100],
...: },
...: columns=["time", "ticker", "price", "quantity"],
...: )
...:
In [8]: quotes = pd.DataFrame(
...: {
...: "time": pd.to_datetime(
...: [
...: "20160525 13:30:00.023",
...: "20160525 13:30:00.023",
...: "20160525 13:30:00.030",
...: "20160525 13:30:00.041",
...: "20160525 13:30:00.048",
...: "20160525 13:30:00.049",
...: "20160525 13:30:00.072",
...: "20160525 13:30:00.075",
...: ]
...: ),
...: "ticker": ["GOOG", "MSFT", "MSFT", "MSFT", "GOOG", "AAPL", "GOOG", "MSFT"],
...: "bid": [720.50, 51.95, 51.97, 51.99, 720.50, 97.99, 720.50, 52.01],
...: "ask": [720.93, 51.96, 51.98, 52.00, 720.93, 98.01, 720.88, 52.03],
...: },
...: columns=["time", "ticker", "bid", "ask"],
...: )
...:
In [9]: trades
Out[9]:
time ticker price quantity
0 2016-05-25 13:30:00.023 MSFT 51.95 75
1 2016-05-25 13:30:00.038 MSFT 51.95 155
2 2016-05-25 13:30:00.048 GOOG 720.77 100
3 2016-05-25 13:30:00.048 GOOG 720.92 100
4 2016-05-25 13:30:00.048 AAPL 98.00 100
[5 rows x 4 columns]
In [10]: quotes
Out[10]:
time ticker bid ask
0 2016-05-25 13:30:00.023 GOOG 720.50 720.93
1 2016-05-25 13:30:00.023 MSFT 51.95 51.96
2 2016-05-25 13:30:00.030 MSFT 51.97 51.98
3 2016-05-25 13:30:00.041 MSFT 51.99 52.00
4 2016-05-25 13:30:00.048 GOOG 720.50 720.93
5 2016-05-25 13:30:00.049 AAPL 97.99 98.01
6 2016-05-25 13:30:00.072 GOOG 720.50 720.88
7 2016-05-25 13:30:00.075 MSFT 52.01 52.03
[8 rows x 4 columns]
Asof 合并基于 on
字段进行连接,通常是一个有序的日期时间字段,在此示例中,我们在 by
字段中使用了分组器。这类似于左外连接,不同之处在于会自动进行向前填充,获取最近的非 NaN 值。
In [11]: pd.merge_asof(trades, quotes, on="time", by="ticker")
Out[11]:
time ticker price quantity bid ask
0 2016-05-25 13:30:00.023 MSFT 51.95 75 51.95 51.96
1 2016-05-25 13:30:00.038 MSFT 51.95 155 51.97 51.98
2 2016-05-25 13:30:00.048 GOOG 720.77 100 720.50 720.93
3 2016-05-25 13:30:00.048 GOOG 720.92 100 720.50 720.93
4 2016-05-25 13:30:00.048 AAPL 98.00 100 NaN NaN
[5 rows x 6 columns]
这将返回一个合并后的 DataFrame,其条目顺序与原始左侧传入的 DataFrame(在此例中为 trades
)相同,并合并了 quotes
的字段。
方法 .rolling()
现在具备时间序列感知能力#
.rolling()
对象现在具备时间序列感知能力,并且可以为 window
参数接受时间序列偏移量(或可转换类型)(GH 13327, GH 12995)。请参阅完整文档此处。
In [12]: dft = pd.DataFrame(
....: {"B": [0, 1, 2, np.nan, 4]},
....: index=pd.date_range("20130101 09:00:00", periods=5, freq="s"),
....: )
....:
In [13]: dft
Out[13]:
B
2013-01-01 09:00:00 0.0
2013-01-01 09:00:01 1.0
2013-01-01 09:00:02 2.0
2013-01-01 09:00:03 NaN
2013-01-01 09:00:04 4.0
[5 rows x 1 columns]
这是一个常规频率索引。使用整数窗口参数可以沿着窗口频率滚动。
In [14]: dft.rolling(2).sum()
Out[14]:
B
2013-01-01 09:00:00 NaN
2013-01-01 09:00:01 1.0
2013-01-01 09:00:02 3.0
2013-01-01 09:00:03 NaN
2013-01-01 09:00:04 NaN
[5 rows x 1 columns]
In [15]: dft.rolling(2, min_periods=1).sum()
Out[15]:
B
2013-01-01 09:00:00 0.0
2013-01-01 09:00:01 1.0
2013-01-01 09:00:02 3.0
2013-01-01 09:00:03 2.0
2013-01-01 09:00:04 4.0
[5 rows x 1 columns]
指定偏移量可以更直观地指定滚动频率。
In [16]: dft.rolling("2s").sum()
Out[16]:
B
2013-01-01 09:00:00 0.0
2013-01-01 09:00:01 1.0
2013-01-01 09:00:02 3.0
2013-01-01 09:00:03 2.0
2013-01-01 09:00:04 4.0
[5 rows x 1 columns]
对于非规则但单调的索引,使用整数窗口进行滚动不会进行任何特殊计算。
In [17]: dft = pd.DataFrame(
....: {"B": [0, 1, 2, np.nan, 4]},
....: index=pd.Index(
....: [
....: pd.Timestamp("20130101 09:00:00"),
....: pd.Timestamp("20130101 09:00:02"),
....: pd.Timestamp("20130101 09:00:03"),
....: pd.Timestamp("20130101 09:00:05"),
....: pd.Timestamp("20130101 09:00:06"),
....: ],
....: name="foo",
....: ),
....: )
....:
In [18]: dft
Out[18]:
B
foo
2013-01-01 09:00:00 0.0
2013-01-01 09:00:02 1.0
2013-01-01 09:00:03 2.0
2013-01-01 09:00:05 NaN
2013-01-01 09:00:06 4.0
[5 rows x 1 columns]
In [19]: dft.rolling(2).sum()
Out[19]:
B
foo
2013-01-01 09:00:00 NaN
2013-01-01 09:00:02 1.0
2013-01-01 09:00:03 3.0
2013-01-01 09:00:05 NaN
2013-01-01 09:00:06 NaN
[5 rows x 1 columns]
使用时间规范会为这些稀疏数据生成可变窗口。
In [20]: dft.rolling("2s").sum()
Out[20]:
B
foo
2013-01-01 09:00:00 0.0
2013-01-01 09:00:02 1.0
2013-01-01 09:00:03 3.0
2013-01-01 09:00:05 NaN
2013-01-01 09:00:06 4.0
[5 rows x 1 columns]
此外,我们现在允许使用可选的 on
参数来指定 DataFrame 中的一个列(而不是默认的索引)。
In [21]: dft = dft.reset_index()
In [22]: dft
Out[22]:
foo B
0 2013-01-01 09:00:00 0.0
1 2013-01-01 09:00:02 1.0
2 2013-01-01 09:00:03 2.0
3 2013-01-01 09:00:05 NaN
4 2013-01-01 09:00:06 4.0
[5 rows x 2 columns]
In [23]: dft.rolling("2s", on="foo").sum()
Out[23]:
foo B
0 2013-01-01 09:00:00 0.0
1 2013-01-01 09:00:02 1.0
2 2013-01-01 09:00:03 3.0
3 2013-01-01 09:00:05 NaN
4 2013-01-01 09:00:06 4.0
[5 rows x 2 columns]
方法 read_csv
对重复列名有了更好的支持#
重复列名现在在 read_csv()
中受到支持,无论它们是在文件中还是作为 names
参数传入(GH 7160, GH 9424)
In [24]: data = "0,1,2\n3,4,5"
In [25]: names = ["a", "b", "a"]
旧的行为:
In [2]: pd.read_csv(StringIO(data), names=names)
Out[2]:
a b a
0 2 1 2
1 5 4 5
第一个 a
列包含了与第二个 a
列相同的数据,而它本应包含值 [0, 3]
。
新的行为:
In [26]: pd.read_csv(StringIO(data), names=names)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[26], line 1
----> 1 pd.read_csv(StringIO(data), names=names)
File ~/work/pandas/pandas/pandas/io/parsers/readers.py:1026, in read_csv(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, date_format, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options, dtype_backend)
1013 kwds_defaults = _refine_defaults_read(
1014 dialect,
1015 delimiter,
(...)
1022 dtype_backend=dtype_backend,
1023 )
1024 kwds.update(kwds_defaults)
-> 1026 return _read(filepath_or_buffer, kwds)
File ~/work/pandas/pandas/pandas/io/parsers/readers.py:617, in _read(filepath_or_buffer, kwds)
614 nrows = kwds.get("nrows", None)
616 # Check for duplicates in names.
--> 617 _validate_names(kwds.get("names", None))
619 # Create the parser.
620 parser = TextFileReader(filepath_or_buffer, **kwds)
File ~/work/pandas/pandas/pandas/io/parsers/readers.py:576, in _validate_names(names)
574 if names is not None:
575 if len(names) != len(set(names)):
--> 576 raise ValueError("Duplicate names are not allowed.")
577 if not (
578 is_list_like(names, allow_sets=False) or isinstance(names, abc.KeysView)
579 ):
580 raise ValueError("Names should be an ordered collection.")
ValueError: Duplicate names are not allowed.
方法 read_csv
直接支持解析 Categorical
数据#
read_csv()
函数现在支持在指定为 dtype 时解析 Categorical
列(GH 10153)。根据数据的结构,与解析后再转换为 Categorical
相比,这可以加快解析时间并降低内存使用。请参阅 io 文档此处。
In [27]: data = """
....: col1,col2,col3
....: a,b,1
....: a,b,2
....: c,d,3
....: """
....:
In [28]: pd.read_csv(StringIO(data))
Out[28]:
col1 col2 col3
0 a b 1
1 a b 2
2 c d 3
[3 rows x 3 columns]
In [29]: pd.read_csv(StringIO(data)).dtypes
Out[29]:
col1 object
col2 object
col3 int64
Length: 3, dtype: object
In [30]: pd.read_csv(StringIO(data), dtype="category").dtypes
Out[30]:
col1 category
col2 category
col3 category
Length: 3, dtype: object
可以使用字典规范将单独的列解析为 Categorical
In [31]: pd.read_csv(StringIO(data), dtype={"col1": "category"}).dtypes
Out[31]:
col1 category
col2 object
col3 int64
Length: 3, dtype: object
注意
生成的类别将始终被解析为字符串(object dtype)。如果类别是数字,可以使用 to_numeric()
函数进行转换,或者根据需要使用其他转换器,例如 to_datetime()
。
In [32]: df = pd.read_csv(StringIO(data), dtype="category")
In [33]: df.dtypes
Out[33]:
col1 category
col2 category
col3 category
Length: 3, dtype: object
In [34]: df["col3"]
Out[34]:
0 1
1 2
2 3
Name: col3, Length: 3, dtype: category
Categories (3, object): ['1', '2', '3']
In [35]: new_categories = pd.to_numeric(df["col3"].cat.categories)
In [36]: df["col3"] = df["col3"].cat.rename_categories(new_categories)
In [37]: df["col3"]
Out[37]:
0 1
1 2
2 3
Name: col3, Length: 3, dtype: category
Categories (3, int64): [1, 2, 3]
Categorical 数据连接#
新增了用于组合 Categorical 数据的函数
union_categoricals()
,详见合并 Categorical 数据(GH 13361, GH 13763, GH 13846, GH 14173)In [38]: from pandas.api.types import union_categoricals In [39]: a = pd.Categorical(["b", "c"]) In [40]: b = pd.Categorical(["a", "b"]) In [41]: union_categoricals([a, b]) Out[41]: ['b', 'c', 'a', 'b'] Categories (3, object): ['b', 'c', 'a']
concat
和append
现在可以将具有不同categories
的category
dtypes 合并为object
dtype(GH 13524)In [42]: s1 = pd.Series(["a", "b"], dtype="category") In [43]: s2 = pd.Series(["b", "c"], dtype="category")
旧的行为:
In [1]: pd.concat([s1, s2])
ValueError: incompatible categories in categorical concat
新的行为:
In [44]: pd.concat([s1, s2])
Out[44]:
0 a
1 b
0 b
1 c
Length: 4, dtype: object
半月偏移#
pandas 新增了频率偏移量:SemiMonthEnd
('SM') 和 SemiMonthBegin
('SMS')。它们分别提供了默认锚定到每月 15 日和月末,以及每月 15 日和月初的日期偏移量。(GH 1543)
In [45]: from pandas.tseries.offsets import SemiMonthEnd, SemiMonthBegin
SemiMonthEnd:
In [46]: pd.Timestamp("2016-01-01") + SemiMonthEnd()
Out[46]: Timestamp('2016-01-15 00:00:00')
In [47]: pd.date_range("2015-01-01", freq="SM", periods=4)
Out[47]: DatetimeIndex(['2015-01-15', '2015-01-31', '2015-02-15', '2015-02-28'], dtype='datetime64[ns]', freq='SM-15')
SemiMonthBegin:
In [46]: pd.Timestamp("2016-01-01") + SemiMonthBegin()
Out[46]: Timestamp('2016-01-15 00:00:00')
In [47]: pd.date_range("2015-01-01", freq="SMS", periods=4)
Out[47]: DatetimeIndex(['2015-01-01', '2015-01-15', '2015-02-01', '2015-02-15'], dtype='datetime64[ns]', freq='SMS-15')
使用锚定后缀,您还可以指定月份中的某一天来替代 15 日。
In [50]: pd.date_range("2015-01-01", freq="SMS-16", periods=4)
Out[50]: DatetimeIndex(['2015-01-01', '2015-01-16', '2015-02-01', '2015-02-16'], dtype='datetime64[ns]', freq='SMS-16')
In [51]: pd.date_range("2015-01-01", freq="SM-14", periods=4)
Out[51]: DatetimeIndex(['2015-01-14', '2015-01-31', '2015-02-14', '2015-02-28'], dtype='datetime64[ns]', freq='SM-14')
新的 Index 方法#
为了与 Series
和 DataFrame
API 更一致,Index
添加了以下方法和选项。
Index
现在支持用于相同形状索引的 .where()
函数(GH 13170)
In [48]: idx = pd.Index(["a", "b", "c"])
In [49]: idx.where([True, False, True])
Out[49]: Index(['a', None, 'c'], dtype='object')
Index
现在支持 .dropna()
以排除缺失值(GH 6194)
In [50]: idx = pd.Index([1, 2, np.nan, 4])
In [51]: idx.dropna()
Out[51]: Index([1.0, 2.0, 4.0], dtype='float64')
对于 MultiIndex
,默认情况下如果任何级别有缺失值,则会删除对应的值。指定 how='all'
只删除所有级别都有缺失值的情况。
In [52]: midx = pd.MultiIndex.from_arrays([[1, 2, np.nan, 4], [1, 2, np.nan, np.nan]])
In [53]: midx
Out[53]:
MultiIndex([(1.0, 1.0),
(2.0, 2.0),
(nan, nan),
(4.0, nan)],
)
In [54]: midx.dropna()
Out[54]:
MultiIndex([(1, 1),
(2, 2)],
)
In [55]: midx.dropna(how="all")
Out[55]:
MultiIndex([(1, 1.0),
(2, 2.0),
(4, nan)],
)
Index
现在支持 .str.extractall()
,它返回一个 DataFrame
,详见此处文档(GH 10008, GH 13156)
In [56]: idx = pd.Index(["a1a2", "b1", "c1"])
In [57]: idx.str.extractall(r"[ab](?P<digit>\d)")
Out[57]:
digit
match
0 0 1
1 2
1 0 1
[3 rows x 1 columns]
Index.astype()
现在接受一个可选的布尔参数 copy
,如果 dtype 要求满足,它允许可选地进行复制(GH 13209)
Google BigQuery 增强功能#
read_gbq()
方法新增了dialect
参数,允许用户指定使用 BigQuery 的旧版 SQL 还是标准 SQL。更多详情请参阅文档(GH 13615)。
细粒度 NumPy 错误状态处理#
之前版本的 pandas 在导入 pandas
时会永久静默 numpy 的 ufunc 错误处理。pandas 这样做是为了抑制在使用 numpy ufuncs 处理缺失数据(通常表示为 NaN
)时产生的警告。不幸的是,这也会静默应用程序中非 pandas 代码产生的合法警告。从 0.19.0 版本开始,pandas 将使用 numpy.errstate
上下文管理器以更细粒度的方式静默这些警告,仅在 pandas 代码库中实际使用这些操作的地方进行。(GH 13109, GH 13145)
升级 pandas 后,您可能会看到 新的 RuntimeWarnings
被代码发出。这些警告很可能是合法的,并且其根本原因在使用先前版本 pandas(仅静默了警告)时就已存在。请在 RuntimeWarning
的来源处使用 numpy.errstate 来控制如何处理这些情况。
方法 get_dummies
现在返回整数 dtypes#
pd.get_dummies
函数现在将独热编码(dummy-encoded)的列返回为小整数,而不是浮点数(GH 8725)。这应该可以改善内存占用。
旧的行为:
In [1]: pd.get_dummies(['a', 'b', 'a', 'c']).dtypes
Out[1]:
a float64
b float64
c float64
dtype: object
新的行为:
In [58]: pd.get_dummies(["a", "b", "a", "c"]).dtypes
Out[58]:
a bool
b bool
c bool
Length: 3, dtype: object
在 to_numeric
中将值向下转换为最小可能的 dtype#
pd.to_numeric()
现在接受一个 downcast
参数,如果可能,它会将数据向下转换为指定的最小数值 dtype(GH 13352)
In [59]: s = ["1", 2, 3]
In [60]: pd.to_numeric(s, downcast="unsigned")
Out[60]: array([1, 2, 3], dtype=uint8)
In [61]: pd.to_numeric(s, downcast="integer")
Out[61]: array([1, 2, 3], dtype=int8)
pandas 开发 API#
作为未来使 pandas API 更统一和易于访问的一部分,我们创建了一个标准的 pandas 子包 pandas.api
来存放公共 API。我们首先在 pandas.api.types
中暴露类型自省函数。更多子包和官方认可的 API 将在未来版本的 pandas 中发布(GH 13147, GH 13634)
以下现在是此 API 的一部分
In [62]: import pprint
In [63]: from pandas.api import types
In [64]: funcs = [f for f in dir(types) if not f.startswith("_")]
In [65]: pprint.pprint(funcs)
['CategoricalDtype',
'DatetimeTZDtype',
'IntervalDtype',
'PeriodDtype',
'infer_dtype',
'is_any_real_numeric_dtype',
'is_array_like',
'is_bool',
'is_bool_dtype',
'is_categorical_dtype',
'is_complex',
'is_complex_dtype',
'is_datetime64_any_dtype',
'is_datetime64_dtype',
'is_datetime64_ns_dtype',
'is_datetime64tz_dtype',
'is_dict_like',
'is_dtype_equal',
'is_extension_array_dtype',
'is_file_like',
'is_float',
'is_float_dtype',
'is_hashable',
'is_int64_dtype',
'is_integer',
'is_integer_dtype',
'is_interval',
'is_interval_dtype',
'is_iterator',
'is_list_like',
'is_named_tuple',
'is_number',
'is_numeric_dtype',
'is_object_dtype',
'is_period_dtype',
'is_re',
'is_re_compilable',
'is_scalar',
'is_signed_integer_dtype',
'is_sparse',
'is_string_dtype',
'is_timedelta64_dtype',
'is_timedelta64_ns_dtype',
'is_unsigned_integer_dtype',
'pandas_dtype',
'union_categoricals']
注意
现在从内部模块 pandas.core.common
调用这些函数将显示 DeprecationWarning
(GH 13990)
其他增强功能#
Timestamp
现在可以接受类似于datetime.datetime()
的位置参数和关键字参数(GH 10758, GH 11630)In [66]: pd.Timestamp(2012, 1, 1) Out[66]: Timestamp('2012-01-01 00:00:00') In [67]: pd.Timestamp(year=2012, month=1, day=1, hour=8, minute=30) Out[67]: Timestamp('2012-01-01 08:30:00')
.resample()
函数现在接受on=
或level=
参数,用于在日期时间列或MultiIndex
级别上进行重采样(GH 13500)In [68]: df = pd.DataFrame( ....: {"date": pd.date_range("2015-01-01", freq="W", periods=5), "a": np.arange(5)}, ....: index=pd.MultiIndex.from_arrays( ....: [[1, 2, 3, 4, 5], pd.date_range("2015-01-01", freq="W", periods=5)], ....: names=["v", "d"], ....: ), ....: ) ....: In [69]: df Out[69]: date a v d 1 2015-01-04 2015-01-04 0 2 2015-01-11 2015-01-11 1 3 2015-01-18 2015-01-18 2 4 2015-01-25 2015-01-25 3 5 2015-02-01 2015-02-01 4 [5 rows x 2 columns]
In [74]: df.resample("M", on="date")[["a"]].sum() Out[74]: a date 2015-01-31 6 2015-02-28 4 [2 rows x 1 columns] In [75]: df.resample("M", level="d")[["a"]].sum() Out[75]: a d 2015-01-31 6 2015-02-28 4 [2 rows x 1 columns]
GbqConnector
的.get_credentials()
方法现在可以首先尝试获取应用程序默认凭据。更多详情请参阅文档(GH 13577)。DatetimeIndex
和Timestamp
的.tz_localize()
方法新增了errors
关键字,因此您可以潜在地将不存在的时间戳强制转换为NaT
。默认行为仍然是引发NonExistentTimeError
(GH 13057)。.to_hdf/read_hdf()
现在接受文件路径的路径对象(例如pathlib.Path
,py.path.local
)(GH 11773)带有
engine='python'
的pd.read_csv()
现在支持decimal
(GH 12933)、na_filter
(GH 13321)和memory_map
选项(GH 13381)。与 Python API 一致,
pd.read_csv()
现在将+inf
解释为正无穷大(GH 13274)pd.read_html()
新增支持na_values
、converters
、keep_default_na
选项(GH 13461)Categorical.astype()
现在接受一个可选的布尔参数copy
,当 dtype 是 categorical 时有效(GH 13209)DataFrame
新增了.asof()
方法,用于根据选定的子集返回最后一个非 NaN 值(GH 13358)如果传入
OrderedDict
对象的列表,DataFrame
构造函数现在将尊重键的顺序(GH 13304)pd.read_html()
新增支持decimal
选项(GH 12907)Series
新增了属性.is_monotonic
,.is_monotonic_increasing
,.is_monotonic_decreasing
,类似于Index
(GH 13336)DataFrame.to_sql()
现在允许将单个值作为所有列的 SQL 类型(GH 11886)。Series.append
现在支持ignore_index
选项(GH 13677).to_stata()
和StataWriter
现在可以使用字典将列名映射到变量标签,并写入 Stata dta 文件(GH 13535, GH 13536).to_stata()
和StataWriter
会自动将datetime64[ns]
列转换为 Stata 格式%tc
,而不是引发ValueError
(GH 12259)当读取带有重复值标签的 Stata 文件且
convert_categoricals=True
时,read_stata()
和StataReader
会引发更明确的错误消息(GH 13923)DataFrame.style
现在将渲染稀疏化的 MultiIndex(GH 11655)DataFrame.style
现在将显示列级别的名称(例如DataFrame.columns.names
)(GH 13775)DataFrame
新增支持使用df.sort_values(by='...', axis=1)
根据行中的值重新排序列(GH 10806)In [70]: df = pd.DataFrame({"A": [2, 7], "B": [3, 5], "C": [4, 8]}, index=["row1", "row2"]) In [71]: df Out[71]: A B C row1 2 3 4 row2 7 5 8 [2 rows x 3 columns] In [72]: df.sort_values(by="row2", axis=1) Out[72]: B A C row1 3 2 4 row2 5 7 8 [2 rows x 3 columns]
to_html()
现在有一个border
参数来控制开头的<table>
标签中的值。默认值为html.border
选项的值,该选项默认为 1。这也影响 notebook 的 HTML repr,但由于 Jupyter 的 CSS 包含了 border-width 属性,视觉效果是相同的。(GH 11563)。在 sql 函数中使用连接字符串时,如果未安装
sqlalchemy
,则抛出ImportError
(GH 11920)。与 matplotlib 2.0 的兼容性。旧版本的 pandas 也应与 matplotlib 2.0 兼容 (GH 13333)
Timestamp
,Period
,DatetimeIndex
,PeriodIndex
和.dt
访问器新增了.is_leap_year
属性,用于检查日期是否属于闰年 (GH 13727)。astype()
现在接受列名到数据类型映射的字典作为dtype
参数 (GH 12086)。pd.read_json
和DataFrame.to_json
新增支持使用lines
选项读取和写入 json lines,详见 行分隔的 json (GH 9180)。read_excel()
现在支持 true_values 和 false_values 关键字参数 (GH 13347)。groupby()
现在接受标量和单元素列表,用于在非MultiIndex
分组器上指定level
(GH 13907)。Excel 日期列中不可转换的日期将直接返回,不进行转换,并且该列的
object
dtype 将是object
,而不是抛出异常 (GH 10001)。pd.Timedelta(None)
现在被接受并返回NaT
,与pd.Timestamp
保持一致 (GH 13687)。pd.read_stata()
现在可以处理一些格式 111 文件,这些文件由 SAS 在生成 Stata dta 文件时产生 (GH 11526)。Series
和Index
现在支持divmod
,这将返回一个 Series 或 Index 的元组。这在广播规则方面表现得像标准的二元运算符 (GH 14208)。
API 变更#
Series.tolist()
现在将返回 Python 类型#
Series.tolist()
现在将在输出中返回 Python 类型,模仿 NumPy .tolist()
的行为 (GH 10904)。
In [73]: s = pd.Series([1, 2, 3])
旧的行为:
In [7]: type(s.tolist()[0])
Out[7]:
<class 'numpy.int64'>
新的行为:
In [74]: type(s.tolist()[0])
Out[74]: int
Series 不同索引的运算符#
以下 Series
运算符已更改,以便所有运算符(包括 DataFrame
)保持一致 (GH 1134, GH 4581, GH 13538)
Series
比较运算符在index
不同时现在抛出ValueError
。Series
逻辑运算符会对其左右两边的index
进行对齐。
警告
在 0.18.1 版本之前,长度相同的 Series
即使 .index
不同也可以成功比较(结果忽略 .index
)。从 0.19.0 版本开始,这将抛出 ValueError
以更严格。本节还描述了如何保留以前的行为或对齐不同的索引,使用灵活的比较方法,如 .eq
。
因此,Series
和 DataFrame
运算符的行为如下所示
算术运算符#
算术运算符对齐两个 index
(无变化)。
In [75]: s1 = pd.Series([1, 2, 3], index=list("ABC"))
In [76]: s2 = pd.Series([2, 2, 2], index=list("ABD"))
In [77]: s1 + s2
Out[77]:
A 3.0
B 4.0
C NaN
D NaN
Length: 4, dtype: float64
In [78]: df1 = pd.DataFrame([1, 2, 3], index=list("ABC"))
In [79]: df2 = pd.DataFrame([2, 2, 2], index=list("ABD"))
In [80]: df1 + df2
Out[80]:
0
A 3.0
B 4.0
C NaN
D NaN
[4 rows x 1 columns]
比较运算符#
比较运算符在 .index
不同时抛出 ValueError
。
以前的行为(Series
)
只要两个 Series 长度相同,比较值时会忽略 .index
In [1]: s1 == s2
Out[1]:
A False
B True
C False
dtype: bool
新的行为(Series
)
In [2]: s1 == s2
Out[2]:
ValueError: Can only compare identically-labeled Series objects
注意
要实现与以前版本相同的行为(基于位置比较值,忽略 .index
),请比较两者的 .values
。
In [81]: s1.values == s2.values
Out[81]: array([False, True, False])
如果你想对齐 .index
后比较 Series
,请参阅下面的灵活比较方法部分
In [82]: s1.eq(s2)
Out[82]:
A False
B True
C False
D False
Length: 4, dtype: bool
目前的行为(DataFrame
,无变化)
In [3]: df1 == df2
Out[3]:
ValueError: Can only compare identically-labeled DataFrame objects
逻辑运算符#
逻辑运算符对齐左右两边的 .index
。
以前的行为(Series
),只保留左侧的 index
In [4]: s1 = pd.Series([True, False, True], index=list('ABC'))
In [5]: s2 = pd.Series([True, True, True], index=list('ABD'))
In [6]: s1 & s2
Out[6]:
A True
B False
C False
dtype: bool
新的行为(Series
)
In [83]: s1 = pd.Series([True, False, True], index=list("ABC"))
In [84]: s2 = pd.Series([True, True, True], index=list("ABD"))
In [85]: s1 & s2
Out[85]:
A True
B False
C False
D False
Length: 4, dtype: bool
注意
Series
逻辑运算符用 False
填充 NaN
结果。
注意
要实现与以前版本相同的行为(仅基于左侧索引比较值),可以使用 reindex_like
In [86]: s1 & s2.reindex_like(s1)
Out[86]:
A True
B False
C False
Length: 3, dtype: bool
目前的行为(DataFrame
,无变化)
In [87]: df1 = pd.DataFrame([True, False, True], index=list("ABC"))
In [88]: df2 = pd.DataFrame([True, True, True], index=list("ABD"))
In [89]: df1 & df2
Out[89]:
0
A True
B False
C False
D False
[4 rows x 1 columns]
灵活的比较方法#
Series
的灵活比较方法,如 eq
, ne
, le
, lt
, ge
和 gt
,现在都会对齐两个 index
。如果想要比较具有不同 index
的两个 Series
,请使用这些运算符。
In [90]: s1 = pd.Series([1, 2, 3], index=["a", "b", "c"])
In [91]: s2 = pd.Series([2, 2, 2], index=["b", "c", "d"])
In [92]: s1.eq(s2)
Out[92]:
a False
b True
c False
d False
Length: 4, dtype: bool
In [93]: s1.ge(s2)
Out[93]:
a False
b True
c True
d False
Length: 4, dtype: bool
以前,这与比较运算符的行为相同(见上文)。
Series 在赋值时的类型提升#
Series
在进行赋值时,如果赋值的值与当前 dtype
不兼容,现在会正确地提升 dtype
(GH 13234)。
In [94]: s = pd.Series()
旧的行为:
In [2]: s["a"] = pd.Timestamp("2016-01-01")
In [3]: s["b"] = 3.0
TypeError: invalid type promotion
新的行为:
In [95]: s["a"] = pd.Timestamp("2016-01-01")
In [96]: s["b"] = 3.0
In [97]: s
Out[97]:
a 2016-01-01 00:00:00
b 3.0
Length: 2, dtype: object
In [98]: s.dtype
Out[98]: dtype('O')
.to_datetime()
函数的变更#
以前,如果 .to_datetime()
遇到混合的整数/浮点数和字符串,但没有日期时间,并且使用了 errors='coerce'
,它会将所有值转换为 NaT
。
旧的行为:
In [2]: pd.to_datetime([1, 'foo'], errors='coerce')
Out[2]: DatetimeIndex(['NaT', 'NaT'], dtype='datetime64[ns]', freq=None)
目前的行为:
现在,它将以默认单位 ns
转换整数/浮点数。
In [99]: pd.to_datetime([1, "foo"], errors="coerce")
Out[99]: DatetimeIndex(['1970-01-01 00:00:00.000000001', 'NaT'], dtype='datetime64[ns]', freq=None)
与 .to_datetime()
相关的 Bug 修复#
修复了
pd.to_datetime()
在传递整数或浮点数且未指定unit
但指定了errors='coerce'
时的 bug (GH 13180)。修复了
pd.to_datetime()
在传递无效数据类型(如 bool)时的 bug;现在将尊重errors
关键字参数 (GH 13176)。修复了
pd.to_datetime()
在处理int8
和int16
dtypes 时可能溢出的 bug (GH 13451)。修复了
pd.to_datetime()
在使用errors='ignore'
时,如果包含NaN
且其他字符串无效,会抛出AttributeError
的 bug (GH 12424)。修复了
pd.to_datetime()
在指定unit
时未正确转换浮点数,导致日期时间被截断的 bug (GH 13834)。
合并变更#
合并现在将保留连接键的 dtype
(GH 8596)。
In [100]: df1 = pd.DataFrame({"key": [1], "v1": [10]})
In [101]: df1
Out[101]:
key v1
0 1 10
[1 rows x 2 columns]
In [102]: df2 = pd.DataFrame({"key": [1, 2], "v1": [20, 30]})
In [103]: df2
Out[103]:
key v1
0 1 20
1 2 30
[2 rows x 2 columns]
旧的行为:
In [5]: pd.merge(df1, df2, how='outer')
Out[5]:
key v1
0 1.0 10.0
1 1.0 20.0
2 2.0 30.0
In [6]: pd.merge(df1, df2, how='outer').dtypes
Out[6]:
key float64
v1 float64
dtype: object
新的行为:
我们现在可以保留连接键的 dtype。
In [104]: pd.merge(df1, df2, how="outer")
Out[104]:
key v1
0 1 10
1 1 20
2 2 30
[3 rows x 2 columns]
In [105]: pd.merge(df1, df2, how="outer").dtypes
Out[105]:
key int64
v1 int64
Length: 2, dtype: object
当然,如果引入了缺失值,结果 dtype
将会被向上转型,这与以前的行为相同。
In [106]: pd.merge(df1, df2, how="outer", on="key")
Out[106]:
key v1_x v1_y
0 1 10.0 20
1 2 NaN 30
[2 rows x 3 columns]
In [107]: pd.merge(df1, df2, how="outer", on="key").dtypes
Out[107]:
key int64
v1_x float64
v1_y int64
Length: 3, dtype: object
.describe()
方法的变更#
.describe()
输出索引中的百分位数标识符现在将四舍五入到能保持它们区别开的最低精度 (GH 13104)。
In [108]: s = pd.Series([0, 1, 2, 3, 4])
In [109]: df = pd.DataFrame([0, 1, 2, 3, 4])
旧的行为:
以前,百分位数最多四舍五入到小数点后一位,如果百分位数重复,可能会导致 DataFrame 抛出 ValueError
。
In [3]: s.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[3]:
count 5.000000
mean 2.000000
std 1.581139
min 0.000000
0.0% 0.000400
0.1% 0.002000
0.1% 0.004000
50% 2.000000
99.9% 3.996000
100.0% 3.998000
100.0% 3.999600
max 4.000000
dtype: float64
In [4]: df.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[4]:
...
ValueError: cannot reindex from a duplicate axis
新的行为:
In [110]: s.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[110]:
count 5.000000
mean 2.000000
std 1.581139
min 0.000000
0.01% 0.000400
0.05% 0.002000
0.1% 0.004000
50% 2.000000
99.9% 3.996000
99.95% 3.998000
99.99% 3.999600
max 4.000000
Length: 12, dtype: float64
In [111]: df.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[111]:
0
count 5.000000
mean 2.000000
std 1.581139
min 0.000000
0.01% 0.000400
0.05% 0.002000
0.1% 0.004000
50% 2.000000
99.9% 3.996000
99.95% 3.998000
99.99% 3.999600
max 4.000000
[12 rows x 1 columns]
此外
现在传递重复的
percentiles
将会抛出ValueError
。修复了
.describe()
在具有混合 dtype 列索引的 DataFrame 上可能抛出TypeError
的 bug (GH 13288)。
Period 变更#
PeriodIndex 现在具有 period dtype#
PeriodIndex
现在有了自己的 period
dtype。period
dtype 是 pandas 的扩展 dtype,类似于 category
或 时区感知 dtype(datetime64[ns, tz]
) (GH 13941)。这一变更的结果是,PeriodIndex
不再具有整数 dtype。
旧的行为:
In [1]: pi = pd.PeriodIndex(['2016-08-01'], freq='D')
In [2]: pi
Out[2]: PeriodIndex(['2016-08-01'], dtype='int64', freq='D')
In [3]: pd.api.types.is_integer_dtype(pi)
Out[3]: True
In [4]: pi.dtype
Out[4]: dtype('int64')
新的行为:
In [112]: pi = pd.PeriodIndex(["2016-08-01"], freq="D")
In [113]: pi
Out[113]: PeriodIndex(['2016-08-01'], dtype='period[D]')
In [114]: pd.api.types.is_integer_dtype(pi)
Out[114]: False
In [115]: pd.api.types.is_period_dtype(pi)
Out[115]: True
In [116]: pi.dtype
Out[116]: period[D]
In [117]: type(pi.dtype)
Out[117]: pandas.core.dtypes.dtypes.PeriodDtype
Period('NaT')
现在返回 pd.NaT
#
以前,Period
有自己的 Period('NaT')
表示形式,不同于 pd.NaT
。现在,Period('NaT')
已更改为返回 pd.NaT
(GH 12759, GH 13582)。
旧的行为:
In [5]: pd.Period('NaT', freq='D')
Out[5]: Period('NaT', 'D')
新的行为:
在不提供 freq
选项的情况下,这些操作现在返回 pd.NaT
。
In [118]: pd.Period("NaT")
Out[118]: NaT
In [119]: pd.Period(None)
Out[119]: NaT
为了与 Period
的加减法兼容,pd.NaT
现在支持与 int
的加减法。以前会抛出 ValueError
。
旧的行为:
In [5]: pd.NaT + 1
...
ValueError: Cannot add integral value to Timestamp without freq.
新的行为:
In [120]: pd.NaT + 1
Out[120]: NaT
In [121]: pd.NaT - 1
Out[121]: NaT
PeriodIndex.values
现在返回 Period
对象的数组#
.values
已更改为返回 Period
对象的数组,而不是整数数组 (GH 13988)。
旧的行为:
In [6]: pi = pd.PeriodIndex(['2011-01', '2011-02'], freq='M')
In [7]: pi.values
Out[7]: array([492, 493])
新的行为:
In [122]: pi = pd.PeriodIndex(["2011-01", "2011-02"], freq="M")
In [123]: pi.values
Out[123]: array([Period('2011-01', 'M'), Period('2011-02', 'M')], dtype=object)
Index 的 + / - 不再用于集合操作#
基本 Index 类型和 DatetimeIndex(非数字索引类型)的加减法以前执行集合操作(集合并集和差集)。此行为自 0.15.0 版本以来已被弃用(推荐使用特定的 .union()
和 .difference()
方法),现在已禁用。如果可能,+
和 -
现在用于元素级操作,例如字符串连接或日期时间相减 (GH 8227, GH 14127)。
旧的行为
In [1]: pd.Index(['a', 'b']) + pd.Index(['a', 'c'])
FutureWarning: using '+' to provide set union with Indexes is deprecated, use '|' or .union()
Out[1]: Index(['a', 'b', 'c'], dtype='object')
新的行为: 相同的操作现在将执行元素级加法。
In [124]: pd.Index(["a", "b"]) + pd.Index(["a", "c"])
Out[124]: Index(['aa', 'bc'], dtype='object')
请注意,数字 Index 对象已经执行元素级操作。例如,两个整数 Index 相加的行为没有改变。现在基本 Index
与此行为保持一致。
In [125]: pd.Index([1, 2, 3]) + pd.Index([2, 3, 4])
Out[125]: Index([3, 5, 7], dtype='int64')
此外,由于此更改,现在可以减去两个 DatetimeIndex 对象,结果是一个 TimedeltaIndex。
旧的行为:
In [1]: (pd.DatetimeIndex(['2016-01-01', '2016-01-02'])
...: - pd.DatetimeIndex(['2016-01-02', '2016-01-03']))
FutureWarning: using '-' to provide set differences with datetimelike Indexes is deprecated, use .difference()
Out[1]: DatetimeIndex(['2016-01-01'], dtype='datetime64[ns]', freq=None)
新的行为:
In [126]: (
.....: pd.DatetimeIndex(["2016-01-01", "2016-01-02"])
.....: - pd.DatetimeIndex(["2016-01-02", "2016-01-03"])
.....: )
.....:
Out[126]: TimedeltaIndex(['-1 days', '-1 days'], dtype='timedelta64[ns]', freq=None)
Index.difference 和 .symmetric_difference 的变更#
Index.difference
和 Index.symmetric_difference
现在将更一致地将 NaN
值视为其他任何值 (GH 13514)。
In [127]: idx1 = pd.Index([1, 2, 3, np.nan])
In [128]: idx2 = pd.Index([0, 1, np.nan])
旧的行为:
In [3]: idx1.difference(idx2)
Out[3]: Float64Index([nan, 2.0, 3.0], dtype='float64')
In [4]: idx1.symmetric_difference(idx2)
Out[4]: Float64Index([0.0, nan, 2.0, 3.0], dtype='float64')
新的行为:
In [129]: idx1.difference(idx2)
Out[129]: Index([2.0, 3.0], dtype='float64')
In [130]: idx1.symmetric_difference(idx2)
Out[130]: Index([0.0, 2.0, 3.0], dtype='float64')
Index.unique 始终返回 Index#
Index.unique()
现在将唯一值作为具有相应 dtype
的 Index
返回 (GH 13395)。以前,大多数 Index
类返回 np.ndarray
,而 DatetimeIndex
, TimedeltaIndex
和 PeriodIndex
返回 Index
以保留元数据(如时区)。
旧的行为:
In [1]: pd.Index([1, 2, 3]).unique()
Out[1]: array([1, 2, 3])
In [2]: pd.DatetimeIndex(['2011-01-01', '2011-01-02',
...: '2011-01-03'], tz='Asia/Tokyo').unique()
Out[2]:
DatetimeIndex(['2011-01-01 00:00:00+09:00', '2011-01-02 00:00:00+09:00',
'2011-01-03 00:00:00+09:00'],
dtype='datetime64[ns, Asia/Tokyo]', freq=None)
新的行为:
In [131]: pd.Index([1, 2, 3]).unique()
Out[131]: Index([1, 2, 3], dtype='int64')
In [132]: pd.DatetimeIndex(
.....: ["2011-01-01", "2011-01-02", "2011-01-03"], tz="Asia/Tokyo"
.....: ).unique()
.....:
Out[132]:
DatetimeIndex(['2011-01-01 00:00:00+09:00', '2011-01-02 00:00:00+09:00',
'2011-01-03 00:00:00+09:00'],
dtype='datetime64[ns, Asia/Tokyo]', freq=None)
MultiIndex 构造函数、groupby 和 set_index 保留 categorical dtypes#
MultiIndex.from_arrays
和 MultiIndex.from_product
现在将在 MultiIndex
的 level 中保留 categorical dtype (GH 13743, GH 13854)。
In [133]: cat = pd.Categorical(["a", "b"], categories=list("bac"))
In [134]: lvl1 = ["foo", "bar"]
In [135]: midx = pd.MultiIndex.from_arrays([cat, lvl1])
In [136]: midx
Out[136]:
MultiIndex([('a', 'foo'),
('b', 'bar')],
)
旧的行为:
In [4]: midx.levels[0]
Out[4]: Index(['b', 'a', 'c'], dtype='object')
In [5]: midx.get_level_values[0]
Out[5]: Index(['a', 'b'], dtype='object')
新的行为: 单个 level 现在是一个 CategoricalIndex
。
In [137]: midx.levels[0]
Out[137]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category')
In [138]: midx.get_level_values(0)
Out[138]: CategoricalIndex(['a', 'b'], categories=['b', 'a', 'c'], ordered=False, dtype='category')
MultiIndex.from_product
也进行了类似的更改。因此,groupby
和 set_index
在索引中也保留了 categorical dtypes。
In [139]: df = pd.DataFrame({"A": [0, 1], "B": [10, 11], "C": cat})
In [140]: df_grouped = df.groupby(by=["A", "C"], observed=False).first()
In [141]: df_set_idx = df.set_index(["A", "C"])
旧的行为:
In [11]: df_grouped.index.levels[1]
Out[11]: Index(['b', 'a', 'c'], dtype='object', name='C')
In [12]: df_grouped.reset_index().dtypes
Out[12]:
A int64
C object
B float64
dtype: object
In [13]: df_set_idx.index.levels[1]
Out[13]: Index(['b', 'a', 'c'], dtype='object', name='C')
In [14]: df_set_idx.reset_index().dtypes
Out[14]:
A int64
C object
B int64
dtype: object
新的行为:
In [142]: df_grouped.index.levels[1]
Out[142]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category', name='C')
In [143]: df_grouped.reset_index().dtypes
Out[143]:
A int64
C category
B float64
Length: 3, dtype: object
In [144]: df_set_idx.index.levels[1]
Out[144]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category', name='C')
In [145]: df_set_idx.reset_index().dtypes
Out[145]:
A int64
C category
B int64
Length: 3, dtype: object
read_csv 函数将逐步枚举块#
当调用 read_csv()
并指定 chunksize=n
且未指定索引时,以前每个块都会生成独立的从 0
到 n-1
的索引。现在,它们改为生成递进的索引,第一个块从 0
开始,第二个块从 n
开始,依此类推,以便连接后与不带 chunksize=
参数调用 read_csv()
的结果相同 (GH 12185)。
In [146]: data = "A,B\n0,1\n2,3\n4,5\n6,7"
旧的行为:
In [2]: pd.concat(pd.read_csv(StringIO(data), chunksize=2))
Out[2]:
A B
0 0 1
1 2 3
0 4 5
1 6 7
新的行为:
In [147]: pd.concat(pd.read_csv(StringIO(data), chunksize=2))
Out[147]:
A B
0 0 1
1 2 3
2 4 5
3 6 7
[4 rows x 2 columns]
Sparse 变更#
这些变更使得 pandas 可以处理具有更多 dtypes 的 sparse 数据,并使其数据处理体验更顺畅。
int64 和 bool 类型的支持增强#
Sparse 数据结构现在增强了对 int64
和 bool
dtype
的支持 (GH 667, GH 13849)。
以前,sparse 数据默认为 float64
dtype,即使所有输入都是 int
或 bool
dtype。必须显式指定 dtype
才能创建 int64
dtype 的 sparse 数据。此外,必须显式指定 fill_value
,因为默认值是 np.nan
,它不会出现在 int64
或 bool
数据中。
In [1]: pd.SparseArray([1, 2, 0, 0])
Out[1]:
[1.0, 2.0, 0.0, 0.0]
Fill: nan
IntIndex
Indices: array([0, 1, 2, 3], dtype=int32)
# specifying int64 dtype, but all values are stored in sp_values because
# fill_value default is np.nan
In [2]: pd.SparseArray([1, 2, 0, 0], dtype=np.int64)
Out[2]:
[1, 2, 0, 0]
Fill: nan
IntIndex
Indices: array([0, 1, 2, 3], dtype=int32)
In [3]: pd.SparseArray([1, 2, 0, 0], dtype=np.int64, fill_value=0)
Out[3]:
[1, 2, 0, 0]
Fill: 0
IntIndex
Indices: array([0, 1], dtype=int32)
从 v0.19.0 版本开始,sparse 数据保留输入的 dtype,并使用更合适的 fill_value
默认值(int64
dtype 为 0
,bool
dtype 为 False
)。
In [148]: pd.arrays.SparseArray([1, 2, 0, 0], dtype=np.int64)
Out[148]:
[1, 2, 0, 0]
Fill: 0
IntIndex
Indices: array([0, 1], dtype=int32)
In [149]: pd.arrays.SparseArray([True, False, False, False])
Out[149]:
[True, False, False, False]
Fill: False
IntIndex
Indices: array([0], dtype=int32)
更多详情请参阅文档。
运算符现在保留 dtypes#
Sparse 数据结构现在可以在算术运算后保留
dtype
(GH 13848)。
s = pd.SparseSeries([0, 2, 0, 1], fill_value=0, dtype=np.int64)
s.dtype
s + 1
Sparse 数据结构现在支持
astype
来转换内部dtype
(GH 13900)。
s = pd.SparseSeries([1.0, 0.0, 2.0, 0.0], fill_value=0)
s
s.astype(np.int64)
如果数据包含无法转换为指定 dtype
的值,astype
会失败。请注意,此限制也适用于默认值为 np.nan
的 fill_value
。
In [7]: pd.SparseSeries([1., np.nan, 2., np.nan], fill_value=np.nan).astype(np.int64)
Out[7]:
ValueError: unable to coerce current fill_value nan to int64 dtype
其他 sparse 修复#
子类化的
SparseDataFrame
和SparseSeries
现在在切片或转置时保留类类型 (GH 13787)。具有
bool
dtype 的SparseArray
现在支持逻辑(bool)运算符 (GH 14000)。修复了具有
MultiIndex
的SparseSeries
在使用[]
索引时可能抛出IndexError
的 bug (GH 13144)。修复了具有
MultiIndex
的SparseSeries
在使用[]
索引时结果可能具有普通Index
的 bug (GH 13144)。修复了
SparseDataFrame
中axis=None
没有默认设置为axis=0
的 bug (GH 13048)。修复了使用
object
dtype 创建SparseSeries
和SparseDataFrame
时可能抛出TypeError
的 bug (GH 11633)。修复了
SparseDataFrame
不尊重传入的SparseArray
或SparseSeries
的dtype
和fill_value
的 bug (GH 13866)。修复了
SparseArray
和SparseSeries
不将 ufunc 应用于fill_value
的 bug (GH 13853)。修复了
SparseSeries.abs
错误地保留负fill_value
的 bug (GH 13853)。修复了对多类型
SparseDataFrame
进行单行切片时,以前类型被强制转换为 float 的 bug (GH 13917)。修复了
SparseSeries
切片将整数 dtype 更改为 float 的 bug (GH 8292)。修复了
SparseDataFrame
比较操作可能抛出TypeError
的 bug (GH 13001)。修复了
SparseDataFrame.isnull
抛出ValueError
的 bug (GH 8276)。修复了具有
bool
dtype 的SparseSeries
在表示时可能抛出IndexError
的 bug (GH 13110)。SparseSeries
和SparseDataFrame
中bool
或int64
dtype 的错误可能导致其值显示为float64
dtype 的形式 (GH 13110)使用
SparseArray
和bool
dtype 进行稀疏索引时,错误可能返回不正确的结果 (GH 13985)从
SparseSeries
创建的SparseArray
中,错误可能导致其丢失dtype
(GH 13999)SparseSeries
与密集 Series 进行比较时,错误会返回正常的Series
而不是SparseSeries
(GH 13999)
Indexer dtype 变化#
注意
此变化仅影响在 Windows 上运行的 64 位 Python,并且仅影响相对高级的索引操作
返回索引器数组的方法(如 Index.get_indexer
)会将该数组强制转换为“平台整数”,以便可以直接用于第三方库操作,例如 numpy.take
。以前,平台整数定义为 np.int_
,它对应于 C 整数;但正确的类型,也是现在使用的类型是 np.intp
,它对应于可以容纳指针的 C 整数大小 (GH 3033, GH 13972)。
这些类型在许多平台上是相同的,但在 Windows 上的 64 位 Python 中,np.int_
是 32 位,而 np.intp
是 64 位。此行为的改变提高了在该平台上的许多操作的性能。
旧的行为:
In [1]: i = pd.Index(['a', 'b', 'c'])
In [2]: i.get_indexer(['b', 'b', 'c']).dtype
Out[2]: dtype('int32')
新的行为:
In [1]: i = pd.Index(['a', 'b', 'c'])
In [2]: i.get_indexer(['b', 'b', 'c']).dtype
Out[2]: dtype('int64')
其他 API 变化#
当
warn=True
且实例具有非零纳秒数时,Timestamp.to_pydatetime
将发出UserWarning
,此前这会将消息打印到 stdout (GH 14101)。带有日期时间和时区的
Series.unique()
现在返回带有时区的Timestamp
数组 (GH 13565)。调用
Panel.to_sparse()
将引发NotImplementedError
异常 (GH 13778)。调用
Index.reshape()
将引发NotImplementedError
异常 (GH 12882)。.filter()
强制关键字参数互斥 (GH 12399)。eval
对float32
类型的向上转型规则已更新,使其与 NumPy 的规则更加一致。新行为在将 pandasfloat32
对象乘以标量 float64 时不会向上转型为float64
(GH 12388)。如果在 groupby 或 resample 对象上调用 NumPy ufuncs(如
np.mean
),现在将引发UnsupportedFunctionCall
错误 (GH 12811)。__setitem__
不再将可调用的 rhs 应用为函数,而是直接存储它。直接调用where
以获得之前的行为 (GH 13299)。调用
.sample()
将遵循通过numpy.random.seed(n)
设置的随机种子 (GH 13161)Styler.apply
现在对您的函数必须返回的输出要求更严格。对于axis=0
或axis=1
,输出形状必须相同。对于axis=None
,输出必须是一个 DataFrame,其列和索引标签必须相同 (GH 13222)。如果
Float64Index
包含NaN
值,Float64Index.astype(int)
现在将引发ValueError
(GH 13149)TimedeltaIndex.astype(int)
和DatetimeIndex.astype(int)
现在将返回Int64Index
而不是np.array
(GH 13209)将具有多种频率的
Period
传递给普通Index
现在返回带有object
dtype 的Index
(GH 13664)带有不同频率的
Period
的PeriodIndex.fillna
现在强制转换为object
dtype (GH 13664)来自
DataFrame.boxplot(by=col)
的分面箱线图在return_type
不为 None 时现在返回一个Series
。此前它们返回一个OrderedDict
。请注意,当return_type=None
(默认值)时,它们仍然返回一个二维 NumPy 数组 (GH 12216, GH 7096)。如果提供的模式不是
r
、r+
和a
,pd.read_hdf
现在将引发ValueError
而不是KeyError
。 (GH 13623)pd.read_csv()
、pd.read_table()
和pd.read_hdf()
在 Python 3.x 中处理不存在的文件时,将引发内置的FileNotFoundError
异常;在 Python 2.x 中则向后移植为IOError
(GH 14086)csv 解析器现在会传递更具信息性的异常。异常类型现在是原始异常类型,而不是
CParserError
(GH 13652)。C 引擎中的
pd.read_csv()
现在会在编码的sep
长度超过一个字符时发出ParserWarning
或引发ValueError
(GH 14065)当
DataFrame
包含混合的int64
和uint64
dtypes 时,DataFrame.values
现在将返回float64
,这符合np.find_common_type
的规则 (GH 10364, GH 13917).groupby.groups
现在将返回一个由Index
对象组成的字典,而不是由np.ndarray
或lists
组成的字典 (GH 14293)
弃用#
Series.reshape
和Categorical.reshape
已被弃用,并将在后续版本中移除 (GH 12882, GH 12882)PeriodIndex.to_datetime
已被弃用,建议使用PeriodIndex.to_timestamp
(GH 8254)Timestamp.to_datetime
已被弃用,建议使用Timestamp.to_pydatetime
(GH 8254)Index.to_datetime
和DatetimeIndex.to_datetime
已被弃用,建议使用pd.to_datetime
(GH 8254)pandas.core.datetools
模块已弃用,并将在后续版本中移除 (GH 14094)SparseList
已被弃用,并将在未来版本中移除 (GH 13784)DataFrame.to_html()
和DataFrame.to_latex()
已弃用colSpace
参数,建议使用col_space
(GH 13857)DataFrame.to_sql()
已弃用flavor
参数,因为在未安装 SQLAlchemy 时该参数是多余的 (GH 13611)弃用的
read_csv
关键字顶层函数
pd.ordered_merge()
已重命名为pd.merge_ordered()
,原名称将在未来版本中移除 (GH 13358)Timestamp.offset
属性(以及构造函数中的命名参数)已弃用,建议使用freq
(GH 12160)pd.tseries.util.pivot_annual
已弃用。建议使用pivot_table
作为替代,示例请参见 此处 (GH 736)pd.tseries.util.isleapyear
已弃用,并将在后续版本中移除。类似 datetime 的对象现在具有.is_leap_year
属性 (GH 13727)Panel4D
和PanelND
构造函数已弃用,并将在未来版本中移除。建议使用 xarray 包来表示这些类型的 n 维数据。pandas 提供了to_xarray()
方法来自动化此转换 (GH 13564)。pandas.tseries.frequencies.get_standard_freq
已弃用。请使用pandas.tseries.frequencies.to_offset(freq).rule_code
替代 (GH 13874)pandas.tseries.frequencies.to_offset
的freqstr
关键字已弃用,建议使用freq
(GH 13874)Categorical.from_array
已弃用,并将在未来版本中移除 (GH 13854)
移除先前版本弃用/变化#
SparsePanel
类已被移除 (GH 13778)pd.sandbox
模块已被移除,建议使用外部库pandas-qt
(GH 13670)pandas.io.data
和pandas.io.wb
模块已被移除,建议使用 pandas-datareader 包 (GH 13724)。DataFrame.to_csv()
已弃用engine
参数,该参数已在 0.17.1 版本中弃用 (GH 11274, GH 13419)DataFrame.to_dict()
已弃用outtype
参数,建议使用orient
(GH 13627, GH 8486)pd.Categorical
已弃用直接设置ordered
属性,建议使用set_ordered
方法 (GH 13671)pd.Categorical
已弃用levels
属性,建议使用categories
(GH 8376)DataFrame.to_sql()
已弃用flavor
参数的mysql
选项 (GH 13611)Panel.shift()
已弃用lags
参数,建议使用periods
(GH 14041)pd.Index
已弃用diff
方法,建议使用difference
(GH 13669)pd.DataFrame
已弃用to_wide
方法,建议使用to_panel
(GH 14039)Series.to_csv
已弃用nanRep
参数,建议使用na_rep
(GH 13804)Series.xs
、DataFrame.xs
、Panel.xs
、Panel.major_xs
和Panel.minor_xs
已弃用copy
参数 (GH 13781)str.split
已弃用return_type
参数,建议使用expand
(GH 13701)移除旧版时间规则(偏移别名),该规则自 0.17.0 版本起已弃用(自 0.8.0 版本起已是别名)(GH 13590, GH 13868)。现在旧版时间规则会引发
ValueError
。有关当前支持的偏移量列表,请参见 此处。DataFrame.plot.box
和DataFrame.boxplot
的return_type
参数的默认值从None
更改为"axes"
。这些方法现在默认返回一个 matplotlib 轴对象,而不是艺术家字典。请参见 此处 (GH 6581)。pandas.io.sql
模块中的tquery
和uquery
函数已被移除 (GH 5950)。
性能改进#
改进了稀疏
IntIndex.intersect
的性能 (GH 13082)改进了块数量较大时使用
BlockIndex
进行稀疏算术运算的性能,尽管在此类情况下建议使用IntIndex
(GH 13082)改进了
DataFrame.quantile()
的性能,因为它现在按块操作 (GH 11623)改进了 float64 哈希表操作的性能,修复了 Python 3 中一些非常慢的索引和 groupby 操作 (GH 13166, GH 13334)
改进了
DataFrameGroupBy.transform
的性能 (GH 12737)改进了
Index
和Series
的.duplicated
性能 (GH 10235)改进了
Index.difference
的性能 (GH 12044)改进了
RangeIndex.is_monotonic_increasing
和is_monotonic_decreasing
的性能 (GH 13749)改进了
DatetimeIndex
中 datetime 字符串解析的性能 (GH 13692)改进了
Period
哈希计算的性能 (GH 12817)改进了带时区的 datetime
factorize
的性能 (GH 13750)通过在较大的 Index 上惰性创建索引哈希表,改进了性能 (GH 14266)
改进了
groupby.groups
的性能 (GH 14293)内省内存使用情况时,不再不必要地物化 MultiIndex (GH 14308)
错误修复#
groupby().shift()
中的错误,在极少数情况下按包含缺失值的列分组时,可能导致段错误或数据损坏 (GH 13813)当
axis=1
时,groupby().cumsum()
计算cumprod
的错误。 (GH 13994)pd.to_timedelta()
中的错误,其中errors
参数未被遵守 (GH 13613)io.json.json_normalize()
中的错误,其中非 ASCII 键会引发异常 (GH 13213)在
.plot()
中将非默认索引的Series
作为xerr
或yerr
传递时的错误 (GH 11858)面积图中的错误,如果启用子图或在绘图后移动图例,则图例绘制不正确(需要 matplotlib 1.5.0 才能正确绘制面积图图例)(GH 9161, GH 13544)
使用 object-dtyped
Index
进行DataFrame
赋值时的错误,其中结果列相对于原始对象是可变的。(GH 13522)matplotlib
AutoDataFormatter
中的错误;这恢复了第二级缩放格式并重新添加了微秒级缩放格式 (GH 13131)从固定格式的
HDFStore
中进行选择并指定了start
和/或stop
时,错误现在将返回所选范围 (GH 8287)Categorical.from_codes()
中的错误,当传入无效的ordered
参数时会引发无意义的错误 (GH 14058)在 Windows 上从整数元组构造
Series
时,未返回默认 dtype (int64) 的错误 (GH 13646)TimedeltaIndex
与类似 datetime 的对象相加时,未捕获加法溢出的错误 (GH 14068)多次调用同一对象时,
.groupby(..).resample(..)
中的错误 (GH 13174)当索引名称为 unicode 字符串时,调用
.to_records()
中的错误 (GH 13172)在未实现
.memory_usage()
的对象上调用该方法时的错误 (GH 12924)带有 nans 的
Series.quantile
中的回归错误(也出现在.median()
和.describe()
中);此外,现在使用分位数命名Series
(GH 13098, GH 13146)带有 datetime 值和缺失组的
SeriesGroupBy.transform
中的错误 (GH 13191)空
Series
在类似 datetime 的数值运算中被错误强制转换的错误 (GH 13844)当传入包含带时区 datetime 的
Categorical
时,Categorical
构造函数中的错误 (GH 14190)带有
str
索引的Series.str.extractall()
中的错误,会引发ValueError
(GH 13156)带有单个组和量词的
Series.str.extractall()
中的错误 (GH 13382)DatetimeIndex
和Period
相减时,错误会引发ValueError
或AttributeError
,而不是TypeError
(GH 13078)使用
NaN
和NaT
混合数据创建的Index
和Series
可能没有datetime64
dtype 的错误 (GH 13324)Index
和Series
可能忽略np.datetime64('nat')
和np.timdelta64('nat')
来推断 dtype 的错误 (GH 13324)PeriodIndex
和Period
相减时,错误会引发AttributeError
(GH 13071)PeriodIndex
构造在某些情况下返回float64
索引的错误 (GH 13067)当空时,带
PeriodIndex
的.resample(..)
未正确更改其freq
的错误 (GH 13067)当空
DataFrame
时,.resample(..)
与PeriodIndex
的错误,无法正确保留其类型或名称 (GH 13212)当传递的函数为每组返回标量值时,
groupby(..).apply(..)
中的错误 (GH 13468)。groupby(..).resample(..)
中的错误,传递某些关键字时会引发异常 (GH 13235)在时区感知的
DateTimeIndex
上使用.tz_convert
时发生的错误,该方法依赖索引排序才能得到正确结果 (GH 13306)在使用
dateutil.tz.tzlocal
时,.tz_localize
中的错误,可能返回不正确的结果 (GH 13583)在使用
dateutil.tz.tzlocal
时,DatetimeTZDtype
类型中的错误,无法视为有效的 dtype (GH 13583)pd.read_hdf()
中的错误,当尝试加载一个包含单个 dataset 且带有一个或多个 categorical 列的 HDF 文件时,除非将 key 参数设置为 dataset 的名称,否则会失败。(GH 13231).rolling()
中的错误,允许在构建Rolling()
对象时使用负整数窗口,但在后续聚合时会失败 (GH 13383)使用元组值数据和数字索引对
Series
进行索引时的错误 (GH 13509)打印
pd.DataFrame
时的错误,其中具有object
类型的不寻常元素导致了段错误 (GH 13717)对
Series
进行排序(ranking)时的错误,可能导致段错误 (GH 13445)各种索引类型中的错误,未传播传递的索引的名称 (GH 12309)
DatetimeIndex
中的错误,未遵守copy=True
参数的设置 (GH 13205)在本地时区情况下,
DatetimeIndex.is_normalized
在标准化date_range
时返回不正确的结果 (GH 13459)pd.concat
和.append
中的错误,可能将datetime64
和timedelta
强制转换为包含 Python 内置datetime
或timedelta
的object
类型,而不是Timestamp
或Timedelta
(GH 13626)PeriodIndex.append
中的错误,当结果为object
类型时,可能引发AttributeError
(GH 13221)CategoricalIndex.append
中的错误,可能接受普通的list
(GH 13626)pd.concat
和.append
中的错误,具有相同时区的数据被重置为 UTC (GH 7795)Series
和DataFrame
的.append
中的错误,如果数据包含夏令时边界附近的 datetime,则引发AmbiguousTimeError
(GH 13626)DataFrame.to_csv()
中的错误,即使仅为非数字值指定了引用,浮点值也被引用 (GH 12922, GH 13259)仅包含布尔列时,
DataFrame.describe()
引发ValueError
的错误 (GH 13898)MultiIndex
切片中的错误,当 level 非唯一时,返回了额外元素 (GH 12896).str.replace
中的错误,对于无效替换未引发TypeError
(GH 13438)MultiIndex.from_arrays
中的错误,未检查输入数组长度是否匹配 (GH 13599)cartesian_product
和MultiIndex.from_product
中的错误,当输入数组为空时可能引发异常 (GH 12258)pd.read_csv()
中的错误,在极少数情况下,当分块迭代流/文件时,可能导致段错误或数据损坏 (GH 13703)pd.read_csv()
中的错误,当为na_values
传递包含标量的字典时,导致引发错误 (GH 12224)pd.read_csv()
中的错误,由于未忽略 BOM,导致 BOM 文件被错误解析 (GH 4793)使用
engine='python'
时,pd.read_csv()
中的错误,当为usecols
传递 numpy 数组时引发错误 (GH 12546)pd.read_csv()
中的错误,当索引列作为日期解析并带有thousands
参数时,被错误解析 (GH 14066)使用
engine='python'
时,pd.read_csv()
中的错误,数据转换为数字值后,未检测到NaN
值 (GH 13314)pd.read_csv()
中的错误,其中nrows
参数未针对两种引擎进行适当验证 (GH 10476)使用
engine='python'
时,pd.read_csv()
中的错误,其中大小写混排形式的无穷值未被正确解释 (GH 13274)使用
engine='python'
时,pd.read_csv()
中的错误,其中尾随的NaN
值未被解析 (GH 13320)在 Windows Python 3 上从
tempfile.TemporaryFile
读取时,使用engine='python'
的pd.read_csv()
中的错误 (GH 13398)pd.read_csv()
中的错误,阻止usecols
kwarg 接受单字节 unicode 字符串 (GH 13219)pd.read_csv()
中的错误,阻止usecols
成为一个空集合 (GH 13402)在使用 C 引擎时,
pd.read_csv()
中的错误,其中 NULL 字符未被解析为 NULL (GH 14012)使用
engine='c'
时,pd.read_csv()
中的错误,即使指定了quoting
为None
,也未接受 NULLquotechar
(GH 13411)使用
engine='c'
时,pd.read_csv()
中的错误,当指定quoting
为非数字时,字段未被正确地转换为浮点数 (GH 13411)在 Python 2.x 中,处理非 UTF-8 编码的多字符分隔数据时,
pd.read_csv()
中的错误 (GH 3404)pd.read_csv()
中的错误,其中 utf-xx 的别名(例如 UTF-xx, UTF_xx, utf_xx)引发了UnicodeDecodeError
(GH 13549)pd.read_csv
,pd.read_table
,pd.read_fwf
,pd.read_stata
和pd.read_sas
中的错误,当chunksize
和iterator
都为None
时,文件被解析器打开但未关闭。(GH 13940)StataReader
,StataWriter
,XportReader
和SAS7BDATReader
中的错误,当引发错误时,文件未被正确关闭。(GH 13940)pd.pivot_table()
中的错误,当aggfunc
是一个列表时,margins_name
被忽略 (GH 13354)在传递非整数时,
pd.Series.str.zfill
,center
,ljust
,rjust
, 和pad
中的错误,未引发TypeError
(GH 13598)检查
TimedeltaIndex
中是否存在任何空对象时的错误,该检查总是返回True
(GH 13603)如果包含具有
object
类型的日期时间类对象,则Series
算术中的错误会引发TypeError
(GH 13043)Series.isnull()
和Series.notnull()
中的错误,忽略Period('NaT')
(GH 13737)Series.fillna()
和Series.dropna()
中的错误,不影响Period('NaT')
(GH 13737在
category
类型的Series
上,.fillna(value=np.nan)
错误地引发了KeyError
(GH 14021)扩展 dtype 创建中的错误,其中创建的类型不相同/一致 (GH 13285)
.resample(..)
中的错误,其中 IPython 自省触发了不正确的警告 (GH 13618)NaT
-Period
中的错误,会引发AttributeError
(GH 13071)Series
比较中的错误,如果右侧(rhs)包含NaT
,可能输出不正确的结果 (GH 9005)Series
和Index
比较中的错误,如果它包含具有object
类型的NaT
,可能输出不正确的结果 (GH 13592)Period
加法中的错误,如果Period
在右侧,则引发TypeError
(GH 13069)Period
与Series
或Index
比较中的错误,引发TypeError
(GH 13200)pd.set_eng_float_format()
中的错误,会阻止NaN
和Inf
进行格式化 (GH 11981)使用
Categorical
类型时,.unstack
中的错误,将.ordered
重置为True
(GH 13249)清理日期时间解析中的一些编译时警告 (GH 13607)
factorize
中的错误,如果数据包含夏令时边界附近的 datetime,则引发AmbiguousTimeError
(GH 13750).set_index
中的错误,如果新索引包含夏令时边界和多层级,则引发AmbiguousTimeError
(GH 12920).shift
中的错误,如果数据包含夏令时边界附近的 datetime,则引发AmbiguousTimeError
(GH 13926)pd.read_hdf()
中的错误,当DataFrame
包含 categorical 列且 query 不匹配任何值时,返回不正确的结果 (GH 13792)使用非字典顺序排序的
MultiIndex
进行索引时,.iloc
中的错误 (GH 13797)在反向排序的
DatetimeIndex
中使用日期字符串进行索引时,.loc
中的错误 (GH 14316)处理零维 NumPy 数组时,
Series
比较运算符中的错误 (GH 13006)groupby
中的错误,其中apply
返回的结果取决于第一个结果是否为None
(GH 12824)groupby(..).nth()
中的错误,如果在调用.head()/.tail()
后调用,组键(group key)会被不一致地包含 (GH 12839).to_html
,.to_latex
和.to_string
中的错误,静默忽略通过formatters
关键字传递的自定义日期时间格式化器 (GH 10690)DataFrame.iterrows()
中的错误,如果定义了Series
子类,则不产生该子类实例 (GH 13977)当
errors='coerce'
且 input 包含不可哈希对象时,pd.to_numeric
中的错误 (GH 13324)无效的
Timedelta
算术和比较中的错误,可能引发ValueError
而不是TypeError
(GH 13624)在
to_datetime
和DatetimeIndex
中的无效日期时间解析错误,可能引发TypeError
而不是ValueError
(GH 11169, GH 11287)使用时区感知的
Timestamp
和不匹配的tz
选项创建Index
时的错误,错误地强制转换了时区 (GH 13692)具有纳秒频率的
DatetimeIndex
中的错误,不包含使用end
指定的时间戳 (GH 13672)使用
np.timedelta64
设置切片时,Series
中的错误 (GH 14155)Index
中的错误,如果datetime
超过datetime64[ns]
边界,则引发OutOfBoundsDatetime
,而不是强制转换为object
类型 (GH 13663)Index
中的错误,可能忽略作为dtype
传递的指定datetime64
或timedelta64
(GH 13981)RangeIndex
中的错误,可以在没有参数的情况下创建,而不是引发TypeError
(GH 13793).value_counts()
中的错误,如果数据超过datetime64[ns]
边界,则引发OutOfBoundsDatetime
(GH 13663)DatetimeIndex
中的错误,如果输入的np.datetime64
单位不是ns
,则可能引发OutOfBoundsDatetime
(GH 9114)使用单位不是
ns
的np.datetime64
作为object
类型创建Series
时的错误,导致值不正确 (GH 13876)使用 timedelta 数据进行
resample
时的错误,其中数据被转换为浮点数 (GH 13119)。pd.isnull()
pd.notnull()
中的错误,如果输入日期时间类对象的单位不是ns
,则引发TypeError
(GH 13389)pd.merge()
中的错误,如果输入日期时间类对象的单位不是ns
,则可能引发TypeError
(GH 13389)HDFStore
/read_hdf()
中的错误,如果设置了tz
,则丢弃了DatetimeIndex.name
(GH 13884)Categorical.remove_unused_categories()
中的错误,将.codes
dtype 更改为平台 int (GH 13261)使用
as_index=False
的groupby
中的错误,当按包含 categorical 列的多个列进行分组时,返回所有NaN
值 (GH 13204)在
df.groupby(...)[...]
中的 bug,当使用Int64Index
进行 getitem 操作时会引发错误 (GH 13731)在分配给
DataFrame.style
的 CSS 类中,针对索引名称的 bug。之前它们被分配"col_heading level<n> col<c>"
,其中n
是级别数 + 1。现在它们被分配"index_name level<n>"
,其中n
是该 MultiIndex 的正确级别。在
pd.read_gbq()
中可能引发ImportError: No module named discovery
的 bug,这是由于与另一个名为 apiclient 的 python 包存在命名冲突 (GH 13454)在
Index.union
中,在使用带名称的空索引时返回不正确结果的 bug (GH 13432)在 Python3 中使用混合整数索引时,
Index.difference
和DataFrame.join
引发错误的 bug (GH 13432, GH 12814)从时区感知的
datetime64
Series 中减去时区感知的datetime.datetime
时出现的 bug (GH 14088)在
.to_excel()
中的 bug,当 DataFrame 包含带有 NaN 值的标签的 MultiIndex 时出现 (GH 13511)无效的频率偏移字符串(如“D1”、“-2-3H”)可能不会引发
ValueError
的 bug (GH 13930)使用
RangeIndex
级别对分层框架进行concat
和groupby
时出现的 bug (GH 13542)。在
Series.str.contains()
中的 bug,针对仅包含object
dtype 的NaN
值的 Series (GH 14171)groupby dataframe 上的
agg()
函数中的 bug,将datetime64[ns]
列的 dtype 更改为float64
(GH 12821)使用 NumPy ufunc 对
PeriodIndex
进行整数加减操作时引发IncompatibleFrequency
的 bug。注意,建议使用标准运算符如+
或-
,因为标准运算符使用更高效的路径 (GH 13980)对
NaT
进行操作时返回float
而不是datetime64[ns]
的 bug (GH 12941)在
Series
灵活算术方法(如.add()
)中的 bug,当axis=None
时引发ValueError
(GH 13894)在
DataFrame.to_csv()
中,当使用MultiIndex
列时添加了一个多余空行的 bug (GH 6618)在
DatetimeIndex
,TimedeltaIndex
和PeriodIndex.equals()
中的 bug,当输入不是Index
但包含相同值时可能返回True
(GH 13107)对带时区的 datetime 进行赋值时出现的 bug,如果 datetime 接近 DST 边界,赋值可能不起作用 (GH 14146)
在 python 2 中,
pd.eval()
和HDFStore
查询截断长浮点文字的 bug (GH 14241)在
Index
中的 bug,当列不在 df 中且列包含重复值时,引发KeyError
并显示错误的列 (GH 13822)在
Period
和PeriodIndex
中的 bug,当频率具有组合偏移别名时创建错误日期 (GH 13874)在
.to_string()
中的 bug,当使用整数line_width
和index=False
调用时,由于idx
在赋值前被引用,引发 UnboundLocalError 异常。在
eval()
中的 bug,其中resolvers
参数不接受列表 (GH 14095)在
stack
,get_dummies
,make_axis_dummies
中的 bug,它们不保留 (multi)indexes 中的分类 dtype (GH 13854)PeriodIndex
现在可以接受包含pd.NaT
的list
和array
(GH 13430)在
df.groupby
中的 bug,如果分组后的 dataframe 包含空 bin,则.median()
返回任意值 (GH 13629)在
Index.copy()
中的 bug,其中name
参数被忽略了 (GH 14302)
贡献者#
共有 117 人为本次发布贡献了补丁。名字旁有“+”号的人是首次贡献补丁。
Adrien Emery +
Alex Alekseyev
Alex Vig +
Allen Riddell +
Amol +
Amol Agrawal +
Andy R. Terrel +
Anthonios Partheniou
Ben Kandel +
Bob Baxley +
Brett Rosen +
Camilo Cota +
Chris
Chris Grinolds
Chris Warth
Christian Hudon
Christopher C. Aycock
Daniel Siladji +
Douglas McNeil
Drewrey Lupton +
Eduardo Blancas Reyes +
Elliot Marsden +
Evan Wright
Felix Marczinowski +
Francis T. O’Donovan
Geraint Duck +
Giacomo Ferroni +
Grant Roch +
Gábor Lipták
Haleemur Ali +
Hassan Shamim +
Iulius Curt +
Ivan Nazarov +
Jeff Reback
Jeffrey Gerard +
Jenn Olsen +
Jim Crist
Joe Jevnik
John Evans +
John Freeman
John Liekezer +
John W. O’Brien
John Zwinck +
Johnny Gill +
Jordan Erenrich +
Joris Van den Bossche
Josh Howes +
Jozef Brandys +
Ka Wo Chen
Kamil Sindi +
Kerby Shedden
Kernc +
Kevin Sheppard
Matthieu Brucher +
Maximilian Roos
Michael Scherer +
Mike Graham +
Mortada Mehyar
Muhammad Haseeb Tariq +
Nate George +
Neil Parley +
Nicolas Bonnotte
OXPHOS
Pan Deng / Zora +
Paul +
Paul Mestemaker +
Pauli Virtanen
Pawel Kordek +
Pietro Battiston
Piotr Jucha +
Ravi Kumar Nimmi +
Robert Gieseke
Robert Kern +
Roger Thomas
Roy Keyes +
Russell Smith +
Sahil Dua +
Sanjiv Lobo +
Sašo Stanovnik +
Shawn Heide +
Sinhrks
Stephen Kappel +
Steve Choi +
Stewart Henderson +
Sudarshan Konge +
Thomas A Caswell
Tom Augspurger
Tom Bird +
Uwe Hoffmann +
WillAyd +
Xiang Zhang +
YG-Riku +
Yadunandan +
Yaroslav Halchenko
Yuichiro Kaneko +
adneu
agraboso +
babakkeyvani +
c123w +
chris-b1
cmazzullo +
conquistador1492 +
cr3 +
dsm054
gfyoung
harshul1610 +
iamsimha +
jackieleng +
mpuels +
pijucha +
priyankjain +
sinhrks
wcwagner +
yui-knk +
zhangjinjie +
znmean +
颜发才(Yan Facai) +