重复列名 现在在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`
当指定为 dtype 时,`read_csv()` 函数现在支持解析`Categorical`列([GH 10153](https://github.com/pandas-dev/pandas/issues/10153))。根据数据的结构,这可能导致比解析后转换为`Categorical`更快的解析时间和更低的内存使用。在这里查看 io 文档。
```py
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
注意
结果类别将始终被解析为字符串(对象 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]
```### 分类连接
+ 添加了一个用于合并分类的函数`union_categoricals()`,请参阅 Unioning Categoricals ([GH 13361](https://github.com/pandas-dev/pandas/issues/13361), [GH 13763](https://github.com/pandas-dev/pandas/issues/13763), [GH 13846](https://github.com/pandas-dev/pandas/issues/13846), [GH 14173](https://github.com/pandas-dev/pandas/issues/14173))
```py
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](https://github.com/pandas-dev/pandas/issues/13524))
```py
In [42]: s1 = pd.Series(["a", "b"], dtype="category")
In [43]: s2 = pd.Series(["b", "c"], dtype="category")
```
**先前的行为**:
```py
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 号)和月底,以及月初(1 号)和 15 号的日期偏移量。 ([GH 1543](https://github.com/pandas-dev/pandas/issues/1543))
```py
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`现在支持`.where()`函数进行相同形状的索引 ([GH 13170](https://github.com/pandas-dev/pandas/issues/13170))
```py
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")
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 还是 BigQuery 的标准 SQL。 有关更多详细信息,请参阅文档 (GH 13615). -
to_gbq()
方法现在允许 DataFrame 列顺序与目标表模式不同 (GH 11359). ### 细粒度的 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
现在返回整数数据类���
pd.get_dummies
函数现在返回编码为小整数的虚拟列,而不是浮点数。(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`中可能的最小数据类型
`pd.to_numeric()`现在接受一个`downcast`参数,如果可能的话将数据降级为指定的最小数值数据类型。([GH 13352](https://github.com/pandas-dev/pandas/issues/13352))
```py
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](https://github.com/pandas-dev/pandas/issues/13147), [GH 13634](https://github.com/pandas-dev/pandas/issues/13634))
以下现在是这个 API 的一部分:
```py
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 为分类时生效(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) -
当使用
convert_categoricals=True
读取具有重复值标签的 Stata 文件时,read_stata()
和StataReader
会提出更明确的错误消息 (GH 13923) -
DataFrame.style
现在会渲染稀疏的 MultiIndexes (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]
-
在 I/O 文档中添加了关于读取具有混合 dtypes 的列的危险性以及如何处理的说明 (GH 13746)
-
to_html()
现在具有border
参数来控制开放<table>
标签中的值。默认值为html.border
选项的值,默认为 1。这也会影响笔记本 HTML 表示,但由于 Jupyter 的 CSS 包含了一个 border-width 属性,所以视觉效果是相同的。 (GH 11563) -
当未安装
sqlalchemy
并使用连接字符串时,sql 函数将引发ImportError
错误 (GH 11920) -
与 matplotlib 2.0 兼容。旧版本的 pandas 应该也可以与 matplotlib 2.0 一起工作 (GH 13333)
-
Timestamp
,Period
,DatetimeIndex
,PeriodIndex
和.dt
accessor 现在具有.is_leap_year
属性来检查日期是否属于闰年。 (GH 13727) -
astype()
现在将接受列名到数据类型映射的字典作为dtype
参数。 (GH 12086) -
pd.read_json
和DataFrame.to_json
现在支持使用lines
选项读取和写入 json 行,参见 Line delimited json (GH 9180) -
read_excel()
现在支持true_values
和false_values
关键字参数 (GH 13347) -
groupby()
现在将接受标量和单元素列表以指定非MultiIndex
分组器上的level
。 (GH 13907) -
在 excel 日期列中的不可转换日期将以
object
dtype 返回,而不是引发异常 (GH 10001). -
现在接受
pd.Timedelta(None)
,并将返回NaT
,与pd.Timestamp
相似(GH 13687) -
pd.read_stata()
现在可以处理一些格式为 111 的文件,这些文件是由 SAS 生成 Stata dta 文件时产生的(GH 11526) -
Series
和Index
现在支持divmod
,将返回一个系列或索引的元组。这遵循标准的二元运算符,关于广播规则(GH 14208)的行为。 ### 函数merge_asof
用于 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]
我们也可以只匹配具有先前数据的行,而不是完全匹配。
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
当指定为 dtype 时,read_csv()
函数现在支持解析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]
分类合并
-
添加了一个函数
union_categoricals()
用于合并分类变量,参见 Unioning Categoricals (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 号)和月初(1 号)。(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 方法
下面的方法和选项已添加到Index
中,以使其与Series
和DataFrame
API 更加一致。
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")
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)。 -
to_gbq()
方法现在允许 DataFrame 的列顺序与目标表模式不同(GH 11359)。
细粒度的 NumPy errstate
先前版本的 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
现在返回整数 dtype
pd.get_dummies
函数现在将虚拟编码列返回为小整数,而不是浮点数(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
中将值降级为最小可能的数据类型
pd.to_numeric()
现在接受一个 downcast
参数,如果可能的话,将数据降级为指定的最小数值数据类型 (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
中公开了类型内省函数。未来版本的 pandas 将发布更多的子包和官方认可的 API (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)。 -
pd.read_csv()
使用engine='python'
现已支持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)。 -
当使用
convert_categoricals=True
时,read_stata()
和StataReader
在读取具有重复值标签的 Stata 文件时会引发一个更明确的错误消息(GH 13923)。 -
DataFrame.style
现在将呈现稀疏化的 MultiIndexes(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]
-
添加了关于在读取具有混合数据类型列时可能遇到的问题以及如何处理的 I/O 文档(GH 13746)。
-
to_html()
现在具有一个border
参数,用于控制在开放的<table>
标签中的值。默认值是html.border
选项的值,默认为 1。这也会影响到笔记本的 HTML 表示,但由于 Jupyter 的 CSS 包含了一个 border-width 属性,视觉效果是一样的。(GH 11563). -
当未安装
sqlalchemy
并且使用连接字符串时,在 sql 函数中引发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,请参阅 行分隔的 json。(GH 9180) -
read_excel()
现在支持true_values
和false_values
关键字参数。(GH 13347) -
groupby()
现在接受标量和单元素列表来指定非MultiIndex
分组器上的level
。(GH 13907) -
在 Excel 日期列中,不可转换的日期将不进行转换,并且列将是
object
数据类型,而不是引发异常。(GH 10001) -
pd.Timedelta(None)
现在被接受,并将返回NaT
,与pd.Timestamp
类似。(GH 13687) -
pd.read_stata()
现在可以处理由 SAS 生成 Stata dta 文件时产生的一些格式为 111 的文件。(GH 11526) -
Series
和Index
现在支持divmod
,将返回系列或索引的元组。这与广播规则一致的标准二元运算符行为。(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)
-
当
index
不同时,Series
比较运算符现在会引发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])
如果要比较Series
并对齐其.index
,请参见下面的灵活比较方法部分:
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
逻辑运算符将NaN
结果填充为False
。
注意
要实现与先前版本相同的结果(仅基于左侧索引比较值),可以使用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
现在将正确提升其数据类型以与当前数据类型不兼容的值进行赋值(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`。
**先前行为**:
```py
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()
相关的错误修复:
-
修复了
pd.to_datetime()
在传递整数或浮点数时,没有unit
和errors='coerce'
时的错误(GH 13180)。 -
修复了
pd.to_datetime()
在传递无效数据类型(例如布尔值)时的错误;现在将尊重errors
关键字(GH 13176) -
修复了
pd.to_datetime()
在int8
和int16
数据类型上溢出的错误(GH 13451) -
修复了
pd.to_datetime()
在errors='ignore'
时,NaN
和另一个字符串无效时引发AttributeError
的错误(GH 12424) -
pd.to_datetime()
中的错误,当指定了unit
时,没有正确地转换浮点数,导致截断的 datetime(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
新行为:
我们能够保留连接键
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](https://github.com/pandas-dev/pandas/issues/13104))
```py
In [108]: s = pd.Series([0, 1, 2, 3, 4])
In [109]: df = pd.DataFrame([0, 1, 2, 3, 4])
以前的行为:
百分位数最多舍入到一位小数,如果数据框中的百分位数重复,则可能引发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
。 -
在具有混合 dtype 列索引的 DataFrame 上的
.describe()
中存在错误,以前会引发TypeError
(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 类型和 DatetimeIndex(而不是数值索引类型)的加法和减法以前执行集合操作(集合并和差)。此行为自 0.15.0 版本起已被弃用(推荐使用特定的 `.union()` 和 `.difference()` 方法),现已禁用。在可能的情况下,`+` 和 `-` 现在用于逐元素操作,例如连接字符串或减去日期时间 ([GH 8227](https://github.com/pandas-dev/pandas/issues/8227), [GH 14127](https://github.com/pandas-dev/pandas/issues/14127))。
先前行为:
```py
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
现在与此行为保持一致。
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](https://github.com/pandas-dev/pandas/issues/13514))
```py
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](https://github.com/pandas-dev/pandas/issues/13395))。以前,大多数 `Index` 类返回 `np.ndarray`,而 `DatetimeIndex`、`TimedeltaIndex` 和 `PeriodIndex` 返回 `Index` 以保留元数据,如时区。
**先前行为**:
```py
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` 保留分类 dtype
`MultiIndex.from_arrays` 和 `MultiIndex.from_product` 现在将在 `MultiIndex` 级别中保留分类 dtype ([GH 13743](https://github.com/pandas-dev/pandas/issues/13743), [GH 13854](https://github.com/pandas-dev/pandas/issues/13854)).
```py
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')
新行为: 单级现在是 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
也在索引中保留了分类 dtype
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` 将逐步枚举块
当使用`chunksize=n`调用`read_csv()`,且没有指定索引时,每个块以前都会有独立生成的索引,从`0`到`n-1`。现在,它们被赋予递进的索引,从第一个块开始为`0`,第二个块为`n`,依此类推,以便在连接时与没有`chunksize=`参数调用`read_csv()`的结果相同([GH 12185](https://github.com/pandas-dev/pandas/issues/12185))。
```py
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]
```### 稀疏变更
这些更改使得 pandas 能够处理更多 dtype 的稀疏数据,并且使数据处理体验更加流畅。
#### 类型`int64`和`bool`支持增强
稀疏数据结构现在获得了对`int64`和`bool` `dtype`的增强支持([GH 667](https://github.com/pandas-dev/pandas/issues/667),[GH 13849](https://github.com/pandas-dev/pandas/issues/13849))。
以前,稀疏数据默认为`float64` dtype,即使所有输入都是`int`或`bool` dtype。您必须明确指定`dtype`才能创建具有`int64` dtype 的稀疏数据。此外,必须显式指定`fill_value`,因为默认值为`np.nan`,而`np.nan`不会出现在`int64`或`bool`数据中。
```py
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 起,稀疏数据保留输入的 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)
有关更多详细信息,请参见文档。
运算符现在会保留 dtype
- 稀疏数据结构现在在算术操作后可以保留
dtype
(GH 13848)
s = pd.SparseSeries([0, 2, 0, 1], fill_value=0, dtype=np.int64)
s.dtype
s + 1
- 稀疏数据结构现在支持
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
其他稀疏修复
-
当切片或转置时,子类化的
SparseDataFrame
和SparseSeries
现在会保留类类型。 (GH 13787) -
SparseArray
中的bool
dtype 现在支持逻辑(bool)运算符(GH 14000) -
在使用
MultiIndex
[]
索引的SparseSeries
中可能会引发IndexError
错误(GH 13144) -
在使用
MultiIndex
[]
索引的SparseSeries
中可能出现普通Index
的错误结果(GH 13144) -
SparseDataFrame
中的错误,其中axis=None
未默认为axis=0
(GH 13048) -
在包含
object
dtype 的SparseSeries
和SparseDataFrame
中创建时可能会引发TypeError
的错误(GH 11633) -
SparseDataFrame
中的 Bug 不遵循传递的SparseArray
或SparseSeries
的 dtype 和fill_value
(GH 13866) -
SparseArray
和SparseSeries
中的 Bug 不对fill_value
应用 ufunc (GH 13853) -
SparseSeries.abs
中的 Bug 不正确地保留了负的fill_value
(GH 13853) -
在多类型
SparseDataFrame
上进行单行切片的 Bug,以前强制类型为浮点数 (GH 13917) -
SparseSeries
切片中的 Bug 会将整数 dtype 更改为浮点数 (GH 8292) -
SparseDataFarme
中的比较操作 Bug 可能会引发TypeError
(GH 13001) -
SparseDataFarme.isnull
中的 Bug 会引发ValueError
(GH 8276) -
使用
bool
dtype 的SparseSeries
表示中的 Bug 可能会引发IndexError
(GH 13110) -
SparseSeries
和SparseDataFrame
中bool
或int64
dtype 的 Bug 可能会显示其值,如同float64
dtype 一样 (GH 13110) -
使用
SparseArray
和bool
dtype 进行稀疏索引的 Bug 可能返回不正确的结果 (GH 13985) -
从
SparseSeries
创建的SparseArray
中的 Bug 可能会丢失dtype
(GH 13999) -
SparseSeries
与密集返回正常Series
而不是SparseSeries
的比较中的 Bug (GH 13999) ### 索引器 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](https://github.com/pandas-dev/pandas/issues/14101)).
+ 具有日期时间和时区的`Series.unique()`现在返回带时区的`Timestamp`数组 ([GH 13565](https://github.com/pandas-dev/pandas/issues/13565)).
+ 当调用`Panel.to_sparse()`时将会抛出`NotImplementedError`异常 ([GH 13778](https://github.com/pandas-dev/pandas/issues/13778)).
+ 当调用`Index.reshape()`时将会抛出`NotImplementedError`异常 ([GH 12882](https://github.com/pandas-dev/pandas/issues/12882)).
+ `.filter()`强制互斥的关键字参数 ([GH 12399](https://github.com/pandas-dev/pandas/issues/12399)).
+ `eval`的`float32`类型的 upcasting 规则已更新为与 NumPy 的规则更一致。 如果您将 pandas 的`float32`对象乘以标量 float64,新行为将不会向上转换为`float64` ([GH 12388](https://github.com/pandas-dev/pandas/issues/12388)).
+ 如果在 groupby 或 resample 对象上调用 NumPy ufuncs 如`np.mean`,现在会引发`UnsupportedFunctionCall`错误 ([GH 12811](https://github.com/pandas-dev/pandas/issues/12811)).
+ `__setitem__`将不再将可调用的 rhs 应用为函数而不是存储它。 直接调用`where`以获取以前的行为 ([GH 13299](https://github.com/pandas-dev/pandas/issues/13299)).
+ 调用`.sample()`将尊重通过`numpy.random.seed(n)`设置的随机种子 ([GH 13161](https://github.com/pandas-dev/pandas/issues/13161))
+ `Styler.apply`现在对您的函数必须返回的输出更严格。 对于`axis=0`或`axis=1`,输出形状必须相同。 对于`axis=None`,输出必须是具有相同列和索引标签的 DataFrame ([GH 13222](https://github.com/pandas-dev/pandas/issues/13222)).
+ 调用`Float64Index.astype(int)`现在如果`Float64Index`包含`NaN`值将会抛出`ValueError`异常 ([GH 13149](https://github.com/pandas-dev/pandas/issues/13149))
+ `TimedeltaIndex.astype(int)`和`DatetimeIndex.astype(int)`现在将返回`Int64Index`而不是`np.array` ([GH 13209](https://github.com/pandas-dev/pandas/issues/13209))
+ 将多频率的`Period`传递给普通的`Index`现在将返回`object` dtype 的`Index` ([GH 13664](https://github.com/pandas-dev/pandas/issues/13664))
+ 使用`Period`的`PeriodIndex.fillna`现在会强制转换为`object` dtype ([GH 13664](https://github.com/pandas-dev/pandas/issues/13664))
+ 从`DataFrame.boxplot(by=col)`绘制的分面箱线图现在在`return_type`不为 None 时返回`Series`。 以前这些返回一个`OrderedDict`。 请注意,当`return_type=None`时,默认情况下,这些仍然返回一个 2-D NumPy 数组 ([GH 12216](https://github.com/pandas-dev/pandas/issues/12216), [GH 7096](https://github.com/pandas-dev/pandas/issues/7096)).
+ `pd.read_hdf`现在将在提供除`r`,`r+`和`a`之外的模式时引发`ValueError`而不是`KeyError`。 ([GH 13623](https://github.com/pandas-dev/pandas/issues/13623))
+ 当在不存在的文件上调用`pd.read_csv()`、`pd.read_table()`和`pd.read_hdf()`时,Python 3.x 将引发内置的`FileNotFoundError`异常;这在 Python 2.x 中回溯为`IOError`([GH 14086](https://github.com/pandas-dev/pandas/issues/14086))
+ csv 解析器会传递更多信息的异常。异常类型现在将是原始异常类型,而不是`CParserError`([GH 13652](https://github.com/pandas-dev/pandas/issues/13652))。
+ 当`sep`编码超过一个字符长时,C 引擎中的`pd.read_csv()`现在会发出`ParserWarning`或引发`ValueError`([GH 14065](https://github.com/pandas-dev/pandas/issues/14065))
+ `DataFrame.values`现在将返回`float64`,具有混合`int64`和`uint64` dtypes 的`DataFrame`,符合`np.find_common_type`([GH 10364](https://github.com/pandas-dev/pandas/issues/10364)、[GH 13917](https://github.com/pandas-dev/pandas/issues/13917))
+ `.groupby.groups`现在将返回一个`Index`对象的字典,而不是`np.ndarray`或`lists`的字典([GH 14293](https://github.com/pandas-dev/pandas/issues/14293))
### `Series.tolist()`现在将返回 Python 类型
`Series.tolist()`现在将以 Python 类型返回输出,模仿 NumPy 的`.tolist()`行为([GH 10904](https://github.com/pandas-dev/pandas/issues/10904))
```py
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)
-
当
index
不同时,Series
比较运算符现在会引发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])
如果您想比较Series
并对齐其.index
,请参见下面的灵活比较方法部分:
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
结果。
注意
要实现与先前版本相同的结果(仅基于左侧index
比较值),可以使用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
以前,这与比较运算符的工作方式相同(见上文)。
算术运算符
算术运算符会对齐两个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
结果。
注意
要实现与先前版本相同的结果(仅基于左侧index
比较值),可以使用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()
相关的错误修复:
-
在传递整数或浮点数时,且没有
unit
和errors='coerce'
时,pd.to_datetime()
存在错误(GH 13180)。 -
在传递无效数据类型(例如布尔值)时,
pd.to_datetime()
存在错误;现在将尊重errors
关键字(GH 13176) -
pd.to_datetime()
中的错误,在int8
和int16
数据类型上溢出 (GH 13451) -
在
errors='ignore'
时,pd.to_datetime()
中的错误会引发AttributeError
,并且另一个字符串无效 (GH 12424) -
在指定
unit
时,pd.to_datetime()
中的错误未正确转换浮点数,导致截断的日期时间 (GH 13834)
合并更改
合并现在将保留连接键的数据类型 (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
新行为:
我们能够保留连接键
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
当然,如果引入了缺失值,那么结果的数据类型将被提升,这与以前的情况相同。
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])
先前的行为:
百分位数最多四舍五入到小数点后一位,如果数据框中的百分位数重复,可能会引发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
。 -
在具有混合数据类型列索引的 DataFrame 上调用
.describe()
时出现的错误,之前会引发TypeError
(GH 13288)
Period
更改
PeriodIndex
现在具有period
数据类型
PeriodIndex
现在具有自己的period
数据类型。period
数据类型是一种类似于category
或时区感知数据类型 (datetime64[ns, tz]
) 的 pandas 扩展数据类型 (GH 13941)。由于这个改变,PeriodIndex
不再具有整数数据类型:
先前的行为:
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
具有与pd.NaT
不同的Period('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)
PeriodIndex
现在具有period
数据类型
PeriodIndex
现在具有自己的 period
dtype。period
dtype 是一个类似于 category
或 时区感知 dtype (datetime64[ns, tz]
) 的 pandas 扩展 dtype。由于这个改变,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
。
先前的行为:
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
对象的数组,而不是整数数组。
先前的行为:
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()
方法),现在已被禁用。现在尽可能使用 +
和 -
进行逐元素操作,例如连接字符串或减去日期时间。
先前的行为:
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
已经与此行为保持一致。
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
值视为任何其他值。
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
返回。先前,大多数 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
保留分类 dtype
MultiIndex.from_arrays
和 MultiIndex.from_product
现在将在MultiIndex
级别中保留分类 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')
新行为:单个级别现在是一个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
也在索引中保留了分类 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
将逐步枚举块
当使用chunksize=n
调用read_csv()
并且没有指定索引时,每个块过去都有一个独立生成的索引,从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]
稀疏变更
这些变化允许 pandas 处理更多 dtypes 的稀疏数据,并使数据处理体验更加顺畅。
类型int64
和bool
支持增强
稀疏数据结构现在增强支持int64
和bool
dtype
(GH 667,GH 13849)。
以前,稀疏数据默认情况下为float64
dtype
,即使所有输入都是int
或bool
dtype
。您必须显式指定dtype
才能创建具有int64
dtype
的稀疏数据。此外,必须显式指定fill_value
,因为默认值为np.nan
,而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 开始,稀疏数据保留输入 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
- 稀疏数据结构现在可以在算术运算后保留
dtype
(GH 13848)
s = pd.SparseSeries([0, 2, 0, 1], fill_value=0, dtype=np.int64)
s.dtype
s + 1
- 稀疏数据结构现在支持
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
其他稀疏修复
-
继承的
SparseDataFrame
和SparseSeries
现在在切片或转置时保留类类型。 (GH 13787) -
SparseArray
与bool
dtype 现在支持逻辑(bool)运算符(GH 14000) -
使用
MultiIndex
[]
索引的SparseSeries
的错误可能会引发IndexError
(GH 13144) -
具有
MultiIndex
[]
索引的SparseSeries
的错误可能具有普通的Index
结果(GH 13144) -
在
SparseDataFrame
中的错误,其中axis=None
没有默认为axis=0
(GH 13048) -
使用
object
dtype 创建SparseSeries
和SparseDataFrame
的错误可能会引发TypeError
(GH 11633) -
在
SparseDataFrame
中的错误不尊重传递的SparseArray
或SparseSeries
的 dtype 和fill_value
(GH 13866) -
在
SparseArray
和SparseSeries
中不应用 ufunc 到fill_value
的错误(GH 13853) -
SparseSeries.abs
中的错误不正确地保留了负的fill_value
(GH 13853) -
在多类型
SparseDataFrame
上的单行切片中的错误,之前类型被强制为浮点数(GH 13917) -
在
SparseSeries
切片中的错误将整数 dtype 更改为浮点数(GH 8292) -
在
SparseDataFarme
比较操作中的错误可能会引发TypeError
(GH 13001) -
在
SparseDataFarme.isnull
中的错误引发了ValueError
(GH 8276) -
在
SparseSeries
表示中带有bool
dtype 的错误可能会引发IndexError
(GH 13110) -
具有
bool
或int64
dtype 的SparseSeries
和SparseDataFrame
的错误可能显示其值像float64
dtype 一样(GH 13110) -
使用
bool
dtype 的SparseArray
进行稀疏索引可能返回不正确的结果(GH 13985) -
从
SparseSeries
创建的SparseArray
中的错误可能会丢失dtype
(GH 13999) -
与密集比较的
SparseSeries
的错误返回普通的Series
而不是SparseSeries
(GH 13999)
类型int64
和bool
的支持增强
稀疏数据结构现在增强了对int64
和bool
dtype
的支持(GH 667, GH 13849)。
以前,即使所有输入都是 int
或 bool
dtype,稀疏数据默认为 float64
dtype。您必须显式指定 dtype
来创建具有 int64
dtype 的稀疏数据。此外,fill_value
必须显式指定,因为默认值为 np.nan
,而 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 开始,稀疏数据保留输入的 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)
更多详情请参见文档。
现在运算符会保留 dtype
- 稀疏数据结构现在可以在算术操作后保留
dtype
(GH 13848)
s = pd.SparseSeries([0, 2, 0, 1], fill_value=0, dtype=np.int64)
s.dtype
s + 1
- 稀疏数据结构现在支持
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
其他稀疏修复
-
当切片或转置时,子类化的
SparseDataFrame
和SparseSeries
现在会保留类类型。 (GH 13787) -
bool
类型的SparseArray
现在支持逻辑(bool)运算(GH 14000) -
MultiIndex
中SparseSeries
的 Bug 使用[]
索引可能引发IndexError
(GH 13144) -
MultiIndex
中SparseSeries
的 Bug 使用[]
索引结果可能有普通的Index
(GH 13144) -
SparseDataFrame
中的 Bug,其中axis=None
不会默认为axis=0
(GH 13048) -
使用
object
dtype 创建SparseSeries
和SparseDataFrame
的 Bug 可能会引发TypeError
(GH 11633) -
SparseDataFrame
中的 Bug 不遵循传递的SparseArray
或SparseSeries
的 dtype 和fill_value
(GH 13866) -
SparseArray
和SparseSeries
中的 Bug 不会将 ufunc 应用到fill_value
(GH 13853) -
SparseSeries.abs
中的 Bug 错误地保留了负的fill_value
(GH 13853) -
单行切片在多类型的
SparseDataFrame
上的 Bug,以前会被强制转换为 float 类型(GH 13917) -
SparseSeries
切片中的 Bug 会将整数 dtype 更改为 float 类型(GH 8292) -
SparseDataFarme
中的比较操作可能会引发TypeError
的 Bug(GH 13001) -
SparseDataFarme.isnull
中的 Bug 引发ValueError
(GH 8276) -
使用
bool
dtype 的SparseSeries
表示中的错误可能会引发IndexError
(GH 13110)。 -
使用
bool
或int64
dtype 的SparseSeries
和SparseDataFrame
中的错误可能会显示其值,例如float64
dtype(GH 13110). -
使用
bool
dtype 的SparseArray
进行稀疏索引的错误可能会返回不正确的结果(GH 13985)。 -
从
SparseSeries
创建的SparseArray
中的错误可能会丢失dtype
(GH 13999)。 -
与密集返回普通
Series
而不是SparseSeries
的SparseSeries
比较中的错误已修复(GH 13999)。
索引器 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 的规则更一致。如果您将 pandas 的float32
对象与标量 float64 相乘,则新行为不会提升为float64
(GH 12388)。 -
现在,如果在分组或重采样对象上调用 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
时,默认情况下,这些仍然返回一个 2-D NumPy 数组 (GH 12216,GH 7096). -
如果
pd.read_hdf
提供的模式不是r
、r+
和a
中的一个,现在会引发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.values
现在会返回float64
类型的混合int64
和uint64
dtypes 的DataFrame
,符合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-likes 现在具有.is_leap_year
属性(GH 13727) -
Panel4D
和PanelND
构造函数已被弃用,并将在将来的版本中移除。推荐表示这些类型的 n 维数据的方法是使用xarray package。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 package(GH 13724) -
pandas.tools.rplot
模块已被移除,转而使用seaborn package(GH 13855) -
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()
已经放弃了mysql
选项,用于flavor
参数(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 axes,而不是一个艺术家字典。请参阅这里(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
中日期时间字符串解析的性能(GH 13692)。 -
改进了
Period
的哈希性能(GH 12817)。 -
改进了带有时区的日期时间的
factorize
的性能(GH 13750)。 -
通过在更大的索引上延迟创建索引哈希表,改进了索引性能(GH 14266)。
-
改进了
groupby.groups
的性能。(GH 14293) -
当检查内存使用情况时,不必要地实现一个 MultiIndex。(GH 14308)
修复的 bug
-
在
groupby().shift()
中存在的一个 bug,在按列分组时,当存在缺失值时,在极少情况下可能导致段错误或数据损坏。(GH 13813) -
在
groupby().cumsum()
中存在的一个 bug,在axis=1
时计算cumprod
。(GH 13994) -
在
pd.to_timedelta()
中存在的一个 bug,未能尊重errors
参数。(GH 13613) -
在
io.json.json_normalize()
中存在的一个 bug,非 ASCII 键会引发异常。(GH 13213) -
在
.plot()
中将非默认索引的Series
作为xerr
或yerr
传递时存在的一个 bug。(GH 11858) -
在区域图绘制中存在的一个 bug,如果启用了子图或在绘图后移动图例,图例会被错误地绘制(需要 matplotlib 1.5.0 才能正确绘制区域图图例)。(GH 9161, GH 13544)
-
在使用对象数据类型
Index
进行DataFrame
赋值时存在的一个 bug,导致结果列对原始对象可变。(GH 13522) -
在 matplotlib
AutoDataFormatter
中存在的一个 bug;这将恢复第二个缩放格式并重新添加微秒缩放格式。(GH 13131) -
在使用固定格式和指定
start
和/或stop
的HDFStore
进行选择时,现在将返回所选范围。(GH 8287) -
在
Categorical.from_codes()
中存在的一个 bug,当传递无效的ordered
参数时会引发一个无用的错误。(GH 14058) -
在 Windows 上从整数元组构建
Series
时未返回默认的数据类型(int64)的 bug。(GH 13646) -
在
TimedeltaIndex
与类似日期时间对象相加时存在的一个 bug,未能捕获加法溢出。(GH 14068) -
在多次调用相同对象时,
.groupby(..).resample(..)
中存在的一个 bug。(GH 13174) -
在索引名称为 Unicode 字符串时,
.to_records()
中存在的一个 bug。(GH 13172) -
在调用未实现的对象上的
.memory_usage()
中存在的一个 bug。(GH 12924) -
具有 nans 的
Series.quantile
中的回归(也出现在.median()
和.describe()
中);此外,现在使用分位数命名Series
(GH 13098,GH 13146) -
具有日期时间值和缺失组的
SeriesGroupBy.transform
中的错误(GH 13191) -
空
Series
在类似日期时间的数值操作中被错误地强制转换的错误(GH 13844) -
当传递带有时区的日期时间的
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
数据类型的错误(GH 13324) -
可能会忽略
np.datetime64('nat')
和np.timdelta64('nat')
以推断数据类型的错误(GH 13324) -
PeriodIndex
和Period
相减引发AttributeError
的错误(GH 13071) -
在某些情况下返回
float64
索引的PeriodIndex
构造中的错误(GH 13067) -
使用空时,
.resample(..)
中的PeriodIndex
不会适当地更改其freq
的错误(GH 13067) -
使用空
DataFrame
时,.resample(..)
中的PeriodIndex
不会保留其类型或名称的错误(GH 13212) -
当传递的函数每组返回标量值时,
groupby(..).apply(..)
中的错误(GH 13468) -
传递某些关键字会引发异常的
groupby(..).resample(..)
中的错误(GH 13235) -
依赖于索引排序以获得正确结果的 tz-aware
DateTimeIndex
上的.tz_convert
中的错误(GH 13306) -
使用
dateutil.tz.tzlocal
的.tz_localize
可能返回不正确的结果的错误(GH 13583) -
使用
dateutil.tz.tzlocal
的DatetimeTZDtype
数据类型无法被视为有效数据类型的错误(GH 13583) -
Bug in
pd.read_hdf()
在尝试加载具有单个数据集且具有一个或多个分类列的 HDF 文件时失败,除非将 key 参数设置为数据集的名称。(GH 13231) -
Bug in
.rolling()
允许在构建Rolling()
对象时使用负整数窗口,但在聚合时会失败。(GH 13383) -
Bug in 使用元组值数据和数值索引的
Series
索引。(GH 13509) -
Bug in 打印
pd.DataFrame
时,具有object
dtype 的异常元素导致段错误。(GH 13717) -
Bug in 排名
Series
可能导致段错误。(GH 13445) -
Bug in 各种索引类型,未传播传递的索引名称。(GH 12309)
-
Bug in
DatetimeIndex
,未遵守copy=True
。(GH 13205) -
Bug in
DatetimeIndex.is_normalized
对于本地时区的规范化 date_range 返回不正确。(GH 13459) -
Bug in
pd.concat
和.append
可能会将datetime64
和timedelta
强制转换为包含 Python 内置datetime
或timedelta
而不是Timestamp
或Timedelta
的object
dtype。(GH 13626) -
Bug in
PeriodIndex.append
当结果为object
dtype 时可能引发AttributeError
。(GH 13221) -
Bug in
CategoricalIndex.append
可能接受普通的list
。(GH 13626) -
Bug in
pd.concat
和.append
具有相同时区时,会重置为 UTC。(GH 7795) -
Bug in
Series
和DataFrame
.append
如果���据包含接近 DST 边界的日期时间,则引发AmbiguousTimeError
。(GH 13626) -
Bug in
DataFrame.to_csv()
中,即使仅为非数字值指定引号,浮点值也被引用。(GH 12922, GH 13259) -
Bug in
DataFrame.describe()
仅包含布尔列时引发ValueError
。(GH 13898) -
Bug in
MultiIndex
切片中,当级别非唯一时,会返回额外的元素。(GH 12896) -
Bug in
.str.replace
对于无效的替换不会引发TypeError
。(GH 13438) -
Bug in
MultiIndex.from_arrays
未检查输入数组长度是否匹配。(GH 13599) -
在
cartesian_product
和MultiIndex.from_product
中存在一个 bug,可能会因为空输入数组而引发错误(GH 12258)。 -
在极少情况下,使用大块数据流/文件进行迭代时,
pd.read_csv()
中存在一个 bug,可能导致 segfault 或数据损坏(GH 13703)。 -
在
pd.read_csv()
中存在一个 bug,当传递包含标量的字典作为na_values
参数时,会引发错误(GH 12224)。 -
在
pd.read_csv()
中存在一个 bug,由于未忽略 BOM(字节顺序标记),导致 BOM 文件被错误解析(GH 4793)。 -
在
pd.read_csv()
中存在一个 bug,当传递一个 numpy 数组作为usecols
参数时,会引发错误(GH 12546)。 -
当使用
thousands
参数解析日期时,pd.read_csv()
中的索引列被错误解析为日期(GH 14066)。 -
在
pd.read_csv()
中存在一个 bug,当数据被转换为数值后,未能正确检测到NaN
值(GH 13314)。 -
在两种引擎中,
pd.read_csv()
中的nrows
参数未被正确验证(GH 10476)。 -
在
pd.read_csv()
中存在一个 bug,未能正确解释大小写混合形式的无穷大数值(GH 13274)。 -
在
pd.read_csv()
中存在一个 bug,当engine='python'
时,尾随的NaN
值未被解析(GH 13320)。 -
在 Windows 中使用 Python 3 时,从
tempfile.TemporaryFile
读取时,pd.read_csv()
中存在一个 bug(GH 13398)。 -
在
pd.read_csv()
中存在一个 bug,阻止usecols
参数接受单字节 Unicode 字符串(GH 13219)。 -
在
pd.read_csv()
中存在一个 bug,阻止usecols
参数为空集合(GH 13402)。 -
在 C 引擎中,
pd.read_csv()
存在一个 bug,未能将 NULL 字符解析为 NULL(GH 14012)。 -
在
pd.read_csv()
中存在一个 bug,当quoting
被指定为None
时,不接受 NULL 的quotechar
,即使quoting
参数被指定为None
(GH 13411)。 -
在
pd.read_csv()
中存在一个 bug,当引号被指定为非数值时,字段未正确转换为浮点数(GH 13411)。 -
在 Python 2.x 中,
pd.read_csv()
存在一个 bug,处理非 UTF8 编码的、多字符分隔的数据时会出现问题(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
中存在的 Bug,在出现错误时未正确关闭文件。(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) -
在
Series
进行算术运算时,如果包含object
dtype 的日期时间,则引发TypeError
。(GH 13043) -
在
Series.isnull()
和Series.notnull()
中忽略Period('NaT')
。(GH 13737) -
在
Series.fillna()
和Series.dropna()
中不影响Period('NaT')
。(GH 13737) -
在
.fillna(value=np.nan)
中错误地在category
dtype 的Series
上引发KeyError
。(GH 14021) -
在扩展 dtype 创建中存在的 Bug,创建的类型不是 / 不完全相同。(GH 13285)
-
在
.resample(..)
中,IPython 内省错误地触发了不正确的警告。(GH 13618) -
在
NaT
-Period
中引发AttributeError
。(GH 13071) -
在
Series
比较中,如果 rhs 包含NaT
,可能会输出错误的结果。(GH 9005) -
在
Series
和Index
比较中,如果包含object
dtype 的NaT
,可能会输出不正确的结果。(GH 13592) -
在
Period
相加时,如果右侧是Period
,会引发TypeError
。(GH 13069) -
在
Period
和Series
或Index
比较中引发TypeError
。(GH 13200) -
Bug in
pd.set_eng_float_format()
会导致 NaN 和 Inf 的格式化失败(GH 11981) -
在
.unstack
中,使用Categorical
dtype 会重置.ordered
为True
。(GH 13249) -
清理一些编译时警告在日期时间解析中(GH 13607)
-
在
factorize
中存在错误,如果数据包含接近 DST 边界的日期时间,则会引发AmbiguousTimeError
(GH 13750) -
在
.set_index
中存在错误,如果新索引包含 DST 边界和多级时会引发AmbiguousTimeError
(GH 12920) -
在数据包含接近 DST 边界的日期时间时,使用
.shift
会引发AmbiguousTimeError
的错误(GH 13926) -
在
pd.read_hdf()
中存在错误,当DataFrame
具有categorical
列且查询不匹配任何值时,返回的结果可能不正确(GH 13792) -
在使用非 lexsorted MultiIndex 进行索引时,使用
.iloc
存在错误(GH 13797) -
在使用日期字符串进行索引时,如果是逆排序的
DatetimeIndex
,在.loc
中存在错误(GH 14316) -
在处理零维 NumPy 数组时,
Series
比较运算符存在错误(GH 13006) -
在
groupby
中存在错误,如果apply
返回的第一个结果是None
,则返回结果会不同(GH 12824) -
在
groupby(..).nth()
中存在错误,如果在.head()/.tail()
之后调用,组键的包含方式会不一致(GH 12839) -
在
.to_html
、.to_latex
和.to_string
中存在错误,通过formatters
关键字传递的自定义日期时间格式化程序会被静默忽略(GH 10690) -
在
DataFrame.iterrows()
中存在错误,如果已定义但未生成Series
子类,则不会生成(GH 13977) -
在使用
pd.to_numeric
时存在错误,当errors='coerce'
且输入包含非可哈希对象时(GH 13324) -
在无效的
Timedelta
算术和比较中可能会引发ValueError
而不是TypeError
(GH 13624) -
在
to_datetime
和DatetimeIndex
中存在无效日期时间解析的错误,可能会引发TypeError
而不是ValueError
(GH 11169,GH 11287) -
在使用时区感知的
Timestamp
创建的Index
中存在错误,并且tz
选项不匹配时,会错误地强制转换时区(GH 13692) -
在纳秒频率的
DatetimeIndex
中存在错误,不包括使用end
指定的时间戳(GH 13672) -
在
Series
中存在 Bug,在使用np.timedelta64
设置切片时 (GH 14155) -
在
Index
中存在 Bug,如果datetime
超出datetime64[ns]
的范围,则会引发OutOfBoundsDatetime
错误,而不是强制转换为object
数据类型 (GH 13663) -
在
Index
中存在 Bug,可能会忽略作为dtype
传递的指定的datetime64
或timedelta64
(GH 13981) -
在
RangeIndex
中存在 Bug,可以创建无参数的 RangeIndex 而不是引发TypeError
(GH 13793) -
.value_counts()
中存在 Bug,如果数据超出datetime64[ns]
的范围,则会引发OutOfBoundsDatetime
错误 (GH 13663) -
在
DatetimeIndex
中存在 Bug,如果输入的np.datetime64
单位不是ns
,可能会引发OutOfBoundsDatetime
错误 (GH 9114) -
在创建具有其他单位而不是
ns
的np.datetime64
的Series
时存在 Bug,将object
数据类型结果设置为不正确的值 (GH 13876) -
在带有 timedelta 数据的
resample
中存在 Bug,数据被转换为浮点数 (GH 13119) -
使用
pd.isnull()
和pd.notnull()
存在 Bug,如果输入的日期时间类型不是ns
单位,则会引发TypeError
(GH 13389) -
在
pd.merge()
中存在 Bug,如果输入的日期时间类型不是ns
单位,则可能会引发TypeError
(GH 13389) -
在
HDFStore
/read_hdf()
中存在 Bug,如果设置了tz
,则会丢弃DatetimeIndex.name
(GH 13884) -
Categorical.remove_unused_categories()
中存在 Bug,会将.codes
的数据类型更改为平台整数 (GH 13261) -
在
groupby
中存在 Bug,使用as_index=False
在多个列上进行分组时,包括一个分类列,会返回所有 NaN 值 (GH 13204) -
在
df.groupby(...)[...]
中存在 Bug,在使用Int64Index
进行取项时可能会引发错误 (GH 13731) -
在为索引名称分配给
DataFrame.style
的 CSS 类中存在 Bug。先前它们被分配为"col_heading level<n> col<c>"
,其中n
是级别数 + 1。现在它们被分配为"index_name level<n>"
,其中n
是该 MultiIndex 的正确级别。 -
pd.read_gbq()
中存在 Bug,可能会引发ImportError: No module named discovery
,因为与另一个名为 apiclient 的 python 包存在命名冲突 (GH 13454) -
在
Index.union
中存在 Bug,在具有命名空索引的情况下返回错误的结果 (GH 13432) -
在 Python3 中,使用混合整数索引时,
Index.difference
和DataFrame.join
中存在错误 (GH 13432, GH 12814) -
将具有时区的
datetime.datetime
从具有时区的datetime64
series 中减去的 bug (GH 14088) -
当 DataFrame 包含具有 NaN 值的标签的 MultiIndex 时,在
.to_excel()
中存在 bug (GH 13511) -
无效频率偏移字符串如 “D1”、“-2-3H” 可能不会引发
ValueError
的 bug (GH 13930) -
对于具有
RangeIndex
索引级别的分层框架,在concat
和groupby
中存在 bug (GH 13542)。 -
对于只包含
object
dtype 的NaN
值的 Series,Series.str.contains()
中存在 bug (GH 14171) -
在 groupby dataframe 上的
agg()
函数中存在 bug,会将datetime64[ns]
列的 dtype 更改为float64
(GH 12821) -
使用 NumPy 的 ufunc 与
PeriodIndex
结合使用进行整数加法或减法会引发IncompatibleFrequency
错误。建议使用标准运算符如+
或-
,因为标准运算符使用更高效的路径 (GH 13980) -
在对
NaT
进行操作时返回float
而不是datetime64[ns]
的 bug (GH 12941) -
在具有
axis=None
时,Series
的灵活算术方法(如.add()
)引发ValueError
的 bug (GH 13894) -
在具有
MultiIndex
列的DataFrame.to_csv()
中添加了多余的空行的 bug (GH 6618) -
DatetimeIndex
、TimedeltaIndex
和PeriodIndex.equals()
中存在 bug,当输入不是Index
但包含相同值时可能返回True
(GH 13107) -
在具有时区的 datetime 进行赋值时可能不起作用,如果它包含接近 DST 边界的 datetime (GH 14146)
-
在
pd.eval()
和HDFStore
查询中,使用 python 2 会截断长浮点数文字的 bug (GH 14241) -
当列不在 df 中且列包含重复值时,
Index
中存在 bug,会引发KeyError
并显示不正确的列 (GH 13822) -
当频率具有组合偏移别名时,
Period
和PeriodIndex
创建错误日期的 bug (GH 13874) -
在带有整数
line_width
和index=False
的情况下调用.to_string()
时会引发 UnboundLocalError 异常,因为idx
在赋值之前被引用。 -
eval()
中的错误,resolvers
参数不接受列表(GH 14095) -
stack
、get_dummies
、make_axis_dummies
中的错误,不会保留(多重)索引中的分类数据类型(GH 13854) -
PeriodIndex
现在可以接受包含pd.NaT
的list
和array
(GH 13430) -
df.groupby
中的错误,如果分组的数据框包含空箱,.median()
返回任意值(GH 13629) -
Index.copy()
中的错误,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) +
) -
在
Index
中存在 Bug,如果datetime
超出datetime64[ns]
的范围,则会引发OutOfBoundsDatetime
错误,而不是强制转换为object
数据类型 (GH 13663) -
在
Index
中存在 Bug,可能会忽略作为dtype
传递的指定的datetime64
或timedelta64
(GH 13981) -
在
RangeIndex
中存在 Bug,可以创建无参数的 RangeIndex 而不是引发TypeError
(GH 13793) -
.value_counts()
中存在 Bug,如果数据超出datetime64[ns]
的范围,则会引发OutOfBoundsDatetime
错误 (GH 13663) -
在
DatetimeIndex
中存在 Bug,如果输入的np.datetime64
单位不是ns
,可能会引发OutOfBoundsDatetime
错误 (GH 9114) -
在创建具有其他单位而不是
ns
的np.datetime64
的Series
时存在 Bug,将object
数据类型结果设置为不正确的值 (GH 13876) -
在带有 timedelta 数据的
resample
中存在 Bug,数据被转换为浮点数 (GH 13119) -
使用
pd.isnull()
和pd.notnull()
存在 Bug,如果输入的日期时间类型不是ns
单位,则会引发TypeError
(GH 13389) -
在
pd.merge()
中存在 Bug,如果输入的日期时间类型不是ns
单位,则可能会引发TypeError
(GH 13389) -
在
HDFStore
/read_hdf()
中存在 Bug,如果设置了tz
,则会丢弃DatetimeIndex.name
(GH 13884) -
Categorical.remove_unused_categories()
中存在 Bug,会将.codes
的数据类型更改为平台整数 (GH 13261) -
在
groupby
中存在 Bug,使用as_index=False
在多个列上进行分组时,包括一个分类列,会返回所有 NaN 值 (GH 13204) -
在
df.groupby(...)[...]
中存在 Bug,在使用Int64Index
进行取项时可能会引发错误 (GH 13731) -
在为索引名称分配给
DataFrame.style
的 CSS 类中存在 Bug。先前它们被分配为"col_heading level<n> col<c>"
,其中n
是级别数 + 1。现在它们被分配为"index_name level<n>"
,其中n
是该 MultiIndex 的正确级别。 -
pd.read_gbq()
中存在 Bug,可能会引发ImportError: No module named discovery
,因为与另一个名为 apiclient 的 python 包存在命名冲突 (GH 13454) -
在
Index.union
中存在 Bug,在具有命名空索引的情况下返回错误的结果 (GH 13432) -
在 Python3 中,使用混合整数索引时,
Index.difference
和DataFrame.join
中存在错误 (GH 13432, GH 12814) -
将具有时区的
datetime.datetime
从具有时区的datetime64
series 中减去的 bug (GH 14088) -
当 DataFrame 包含具有 NaN 值的标签的 MultiIndex 时,在
.to_excel()
中存在 bug (GH 13511) -
无效频率偏移字符串如 “D1”、“-2-3H” 可能不会引发
ValueError
的 bug (GH 13930) -
对于具有
RangeIndex
索引级别的分层框架,在concat
和groupby
中存在 bug (GH 13542)。 -
对于只包含
object
dtype 的NaN
值的 Series,Series.str.contains()
中存在 bug (GH 14171) -
在 groupby dataframe 上的
agg()
函数中存在 bug,会将datetime64[ns]
列的 dtype 更改为float64
(GH 12821) -
使用 NumPy 的 ufunc 与
PeriodIndex
结合使用进行整数加法或减法会引发IncompatibleFrequency
错误。建议使用标准运算符如+
或-
,因为标准运算符使用更高效的路径 (GH 13980) -
在对
NaT
进行操作时返回float
而不是datetime64[ns]
的 bug (GH 12941) -
在具有
axis=None
时,Series
的灵活算术方法(如.add()
)引发ValueError
的 bug (GH 13894) -
在具有
MultiIndex
列的DataFrame.to_csv()
中添加了多余的空行的 bug (GH 6618) -
DatetimeIndex
、TimedeltaIndex
和PeriodIndex.equals()
中存在 bug,当输入不是Index
但包含相同值时可能返回True
(GH 13107) -
在具有时区的 datetime 进行赋值时可能不起作用,如果它包含接近 DST 边界的 datetime (GH 14146)
-
在
pd.eval()
和HDFStore
查询中,使用 python 2 会截断长浮点数文字的 bug (GH 14241) -
当列不在 df 中且列包含重复值时,
Index
中存在 bug,会引发KeyError
并显示不正确的列 (GH 13822) -
当频率具有组合偏移别名时,
Period
和PeriodIndex
创建错误日期的 bug (GH 13874) -
在带有整数
line_width
和index=False
的情况下调用.to_string()
时会引发 UnboundLocalError 异常,因为idx
在赋值之前被引用。 -
eval()
中的错误,resolvers
参数不接受列表(GH 14095) -
stack
、get_dummies
、make_axis_dummies
中的错误,不会保留(多重)索引中的分类数据类型(GH 13854) -
PeriodIndex
现在可以接受包含pd.NaT
的list
和array
(GH 13430) -
df.groupby
中的错误,如果分组的数据框包含空箱,.median()
返回任意值(GH 13629) -
Index.copy()
中的错误,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) +