1.3.0中的新特性(2021年7月2日)#

这些是Pandas1.3.0中的变化。看见 发行说明 获取完整的更改日志,包括其他版本的Pandas。

警告

阅读新的Excel 2007+时 (.xlsx )文件,默认参数 engine=Noneread_excel() 现在将导致使用 openpyxl 在所有情况下,当选项为 io.excel.xlsx.reader 设置为 "auto" 。以前,某些情况下会使用 xlrd 换成了发动机。看见 What's new 1.2.0 了解这一变化的背景。

增强#

读取CSV或JSON文件时的自定义HTTP标头#

当从不是由fsspec处理的远程URL(例如,HTTP和HTTPS)读取时,词典传递到 storage_options 将用于创建请求中包含的标头。这可用于控制User-Agent标头或发送其他自定义标头 (GH36688 )。例如:

In [1]: headers = {"User-Agent": "pandas"}

In [2]: df = pd.read_csv(
   ...:     "https://download.bls.gov/pub/time.series/cu/cu.item",
   ...:     sep="\t",
   ...:     storage_options=headers
   ...: )
   ...: 
---------------------------------------------------------------------------
HTTPError                                 Traceback (most recent call last)
Input In [2], in <cell line: 1>()
----> 1 df = pd.read_csv(
      2     "https://download.bls.gov/pub/time.series/cu/cu.item",
      3     sep="\t",
      4     storage_options=headers
      5 )

File /usr/local/lib/python3.10/dist-packages/pandas-1.5.0.dev0+697.gf9762d8f52-py3.10-linux-x86_64.egg/pandas/util/_decorators.py:317, in deprecate_nonkeyword_arguments.<locals>.decorate.<locals>.wrapper(*args, **kwargs)
    311 if len(args) > num_allow_args:
    312     warnings.warn(
    313         msg.format(arguments=arguments),
    314         FutureWarning,
    315         stacklevel=stacklevel,
    316     )
--> 317 return func(*args, **kwargs)

File /usr/local/lib/python3.10/dist-packages/pandas-1.5.0.dev0+697.gf9762d8f52-py3.10-linux-x86_64.egg/pandas/io/parsers/readers.py:927, in read_csv(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, 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, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, error_bad_lines, warn_bad_lines, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options)
    912 kwds_defaults = _refine_defaults_read(
    913     dialect,
    914     delimiter,
   (...)
    923     defaults={"delimiter": ","},
    924 )
    925 kwds.update(kwds_defaults)
--> 927 return _read(filepath_or_buffer, kwds)

File /usr/local/lib/python3.10/dist-packages/pandas-1.5.0.dev0+697.gf9762d8f52-py3.10-linux-x86_64.egg/pandas/io/parsers/readers.py:582, in _read(filepath_or_buffer, kwds)
    579 _validate_names(kwds.get("names", None))
    581 # Create the parser.
--> 582 parser = TextFileReader(filepath_or_buffer, **kwds)
    584 if chunksize or iterator:
    585     return parser

File /usr/local/lib/python3.10/dist-packages/pandas-1.5.0.dev0+697.gf9762d8f52-py3.10-linux-x86_64.egg/pandas/io/parsers/readers.py:1421, in TextFileReader.__init__(self, f, engine, **kwds)
   1418     self.options["has_index_names"] = kwds["has_index_names"]
   1420 self.handles: IOHandles | None = None
-> 1421 self._engine = self._make_engine(f, self.engine)

File /usr/local/lib/python3.10/dist-packages/pandas-1.5.0.dev0+697.gf9762d8f52-py3.10-linux-x86_64.egg/pandas/io/parsers/readers.py:1707, in TextFileReader._make_engine(self, f, engine)
   1703     mode = "rb"
   1704 # error: No overload variant of "get_handle" matches argument types
   1705 # "Union[str, PathLike[str], ReadCsvBuffer[bytes], ReadCsvBuffer[str]]"
   1706 # , "str", "bool", "Any", "Any", "Any", "Any", "Any"
-> 1707 self.handles = get_handle(  # type: ignore[call-overload]
   1708     f,
   1709     mode,
   1710     encoding=self.options.get("encoding", None),
   1711     compression=self.options.get("compression", None),
   1712     memory_map=self.options.get("memory_map", False),
   1713     is_text=is_text,
   1714     errors=self.options.get("encoding_errors", "strict"),
   1715     storage_options=self.options.get("storage_options", None),
   1716 )
   1717 assert self.handles is not None
   1718 f = self.handles.handle

File /usr/local/lib/python3.10/dist-packages/pandas-1.5.0.dev0+697.gf9762d8f52-py3.10-linux-x86_64.egg/pandas/io/common.py:667, in get_handle(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)
    664     codecs.lookup_error(errors)
    666 # open URLs
--> 667 ioargs = _get_filepath_or_buffer(
    668     path_or_buf,
    669     encoding=encoding,
    670     compression=compression,
    671     mode=mode,
    672     storage_options=storage_options,
    673 )
    675 handle = ioargs.filepath_or_buffer
    676 handles: list[BaseBuffer]

File /usr/local/lib/python3.10/dist-packages/pandas-1.5.0.dev0+697.gf9762d8f52-py3.10-linux-x86_64.egg/pandas/io/common.py:336, in _get_filepath_or_buffer(filepath_or_buffer, encoding, compression, mode, storage_options)
    334 # assuming storage_options is to be interpreted as headers
    335 req_info = urllib.request.Request(filepath_or_buffer, headers=storage_options)
--> 336 with urlopen(req_info) as req:
    337     content_encoding = req.headers.get("Content-Encoding", None)
    338     if content_encoding == "gzip":
    339         # Override compression based on Content-Encoding header

File /usr/local/lib/python3.10/dist-packages/pandas-1.5.0.dev0+697.gf9762d8f52-py3.10-linux-x86_64.egg/pandas/io/common.py:239, in urlopen(*args, **kwargs)
    233 """
    234 Lazy-import wrapper for stdlib urlopen, as that imports a big chunk of
    235 the stdlib.
    236 """
    237 import urllib.request
--> 239 return urllib.request.urlopen(*args, **kwargs)

File /usr/lib/python3.10/urllib/request.py:216, in urlopen(url, data, timeout, cafile, capath, cadefault, context)
    214 else:
    215     opener = _opener
--> 216 return opener.open(url, data, timeout)

File /usr/lib/python3.10/urllib/request.py:525, in OpenerDirector.open(self, fullurl, data, timeout)
    523 for processor in self.process_response.get(protocol, []):
    524     meth = getattr(processor, meth_name)
--> 525     response = meth(req, response)
    527 return response

File /usr/lib/python3.10/urllib/request.py:634, in HTTPErrorProcessor.http_response(self, request, response)
    631 # According to RFC 2616, "2xx" code indicates that the client's
    632 # request was successfully received, understood, and accepted.
    633 if not (200 <= code < 300):
--> 634     response = self.parent.error(
    635         'http', request, response, code, msg, hdrs)
    637 return response

File /usr/lib/python3.10/urllib/request.py:563, in OpenerDirector.error(self, proto, *args)
    561 if http_err:
    562     args = (dict, 'default', 'http_error_default') + orig_args
--> 563     return self._call_chain(*args)

File /usr/lib/python3.10/urllib/request.py:496, in OpenerDirector._call_chain(self, chain, kind, meth_name, *args)
    494 for handler in handlers:
    495     func = getattr(handler, meth_name)
--> 496     result = func(*args)
    497     if result is not None:
    498         return result

File /usr/lib/python3.10/urllib/request.py:643, in HTTPDefaultErrorHandler.http_error_default(self, req, fp, code, msg, hdrs)
    642 def http_error_default(self, req, fp, code, msg, hdrs):
--> 643     raise HTTPError(req.full_url, code, msg, hdrs, fp)

HTTPError: HTTP Error 403: Forbidden

读写XML文档#

我们添加了I/O支持以读取和呈现浅层版本 XML 包含的文档 read_xml()DataFrame.to_xml() 。使用 lxml 作为解析器,XPath 1.0和XSLT 1.0都可用。 (GH27554 )

In [1]: xml = """<?xml version='1.0' encoding='utf-8'?>
   ...: <data>
   ...:  <row>
   ...:     <shape>square</shape>
   ...:     <degrees>360</degrees>
   ...:     <sides>4.0</sides>
   ...:  </row>
   ...:  <row>
   ...:     <shape>circle</shape>
   ...:     <degrees>360</degrees>
   ...:     <sides/>
   ...:  </row>
   ...:  <row>
   ...:     <shape>triangle</shape>
   ...:     <degrees>180</degrees>
   ...:     <sides>3.0</sides>
   ...:  </row>
   ...:  </data>"""

In [2]: df = pd.read_xml(xml)
In [3]: df
Out[3]:
      shape  degrees  sides
0    square      360    4.0
1    circle      360    NaN
2  triangle      180    3.0

In [4]: df.to_xml()
Out[4]:
<?xml version='1.0' encoding='utf-8'?>
<data>
  <row>
    <index>0</index>
    <shape>square</shape>
    <degrees>360</degrees>
    <sides>4.0</sides>
  </row>
  <row>
    <index>1</index>
    <shape>circle</shape>
    <degrees>360</degrees>
    <sides/>
  </row>
  <row>
    <index>2</index>
    <shape>triangle</shape>
    <degrees>180</degrees>
    <sides>3.0</sides>
  </row>
</data>

有关详细信息,请参阅 编写XML 有关IO工具的用户指南中。

Styler增强功能#

我们提供了一些专注于以下方面的开发 Styler 。另请参阅 Styler documentation 已经修改和完善了 (GH39720GH39317GH40493 )。

DataFrame构造函数支持 copy=False 使用DICT#

当将词典传递给 DataFrame 使用 copy=False ,将不再复制副本 (GH32960 )。

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

In [4]: df = pd.DataFrame({"A": arr, "B": arr.copy()}, copy=False)

In [5]: df
Out[5]: 
   A  B
0  1  1
1  2  2
2  3  3

[3 rows x 2 columns]

df["A"] 仍然是一种观点 arr

In [6]: arr[0] = 0

In [7]: assert df.iloc[0, 0] == 0

未通过时的默认行为 copy 将保持不变,即将创建副本。

PyArrow支持的字符串数据类型#

我们已经增强了 StringDtype ,一种专用于字符串数据的扩展类型。 (GH39908 )

现在可以指定一个 storage 关键字选项至 StringDtype 。使用Pandas选项或使用指定数据类型 dtype='string[pyarrow]' 以允许由PyArrow数组而不是由Python对象的NumPy数组支持String数组。

需要安装PyArrow 1.0.0或更高版本才能安装由PyArrow支持的StringArray。

警告

string[pyarrow] 目前被认为是试验性的。API的实现和部分内容可能会在没有任何警告的情况下发生更改。

In [8]: pd.Series(['abc', None, 'def'], dtype=pd.StringDtype(storage="pyarrow"))
Out[8]: 
0     abc
1    <NA>
2     def
Length: 3, dtype: string

您可以使用别名 "string[pyarrow]" 也是。

In [9]: s = pd.Series(['abc', None, 'def'], dtype="string[pyarrow]")

In [10]: s
Out[10]: 
0     abc
1    <NA>
2     def
Length: 3, dtype: string

您还可以使用Pandas选项创建一个PyArrow支持的字符串数组。

In [11]: with pd.option_context("string_storage", "pyarrow"):
   ....:     s = pd.Series(['abc', None, 'def'], dtype="string")
   ....: 

In [12]: s
Out[12]: 
0     abc
1    <NA>
2     def
Length: 3, dtype: string

通常的字符串访问器方法可以工作。在适当的情况下,DataFrame的系列或列的返回类型也将具有字符串数据类型。

In [13]: s.str.upper()
Out[13]: 
0     ABC
1    <NA>
2     DEF
Length: 3, dtype: string

In [14]: s.str.split('b', expand=True).dtypes
Out[14]: 
0    string
1    string
Length: 2, dtype: object

返回整数的字符串访问器方法将返回值 Int64Dtype

In [15]: s.str.count("a")
Out[15]: 
0       1
1    <NA>
2       0
Length: 3, dtype: Int64

居中的日期时间样式的滚动窗口#

在使用类似DateTime的索引对DataFrame和Series对象执行滚动计算时,现在可以使用居中的类似DateTime的窗口 (GH38780 )。例如:

In [16]: df = pd.DataFrame(
   ....:     {"A": [0, 1, 2, 3, 4]}, index=pd.date_range("2020", periods=5, freq="1D")
   ....: )
   ....: 

In [17]: df
Out[17]: 
            A
2020-01-01  0
2020-01-02  1
2020-01-03  2
2020-01-04  3
2020-01-05  4

[5 rows x 1 columns]

In [18]: df.rolling("2D", center=True).mean()
Out[18]: 
              A
2020-01-01  0.5
2020-01-02  1.5
2020-01-03  2.5
2020-01-04  3.5
2020-01-05  4.0

[5 rows x 1 columns]

其他增强功能#

值得注意的错误修复#

这些错误修复可能会带来显著的行为变化。

Categorical.unique 现在始终保持与原始数据类型相同的数据类型#

以前,当调用 Categorical.unique() 对于分类数据,新数组中未使用的类别将被删除,从而使新数组的数据类型不同于原始数组 (GH18291 )

作为这方面的一个例子,给出:

In [19]: dtype = pd.CategoricalDtype(['bad', 'neutral', 'good'], ordered=True)

In [20]: cat = pd.Categorical(['good', 'good', 'bad', 'bad'], dtype=dtype)

In [21]: original = pd.Series(cat)

In [22]: unique = original.unique()

以前的行为

In [1]: unique
['good', 'bad']
Categories (2, object): ['bad' < 'good']
In [2]: original.dtype == unique.dtype
False

新行为

In [23]: unique
Out[23]: 
['good', 'bad']
Categories (3, object): ['bad' < 'neutral' < 'good']

In [24]: original.dtype == unique.dtype
Out[24]: True

将数据类型保留在 DataFrame.combine_first()#

DataFrame.combine_first() 现在将保留数据类型 (GH7509 )

In [25]: df1 = pd.DataFrame({"A": [1, 2, 3], "B": [1, 2, 3]}, index=[0, 1, 2])

In [26]: df1
Out[26]: 
   A  B
0  1  1
1  2  2
2  3  3

[3 rows x 2 columns]

In [27]: df2 = pd.DataFrame({"B": [4, 5, 6], "C": [1, 2, 3]}, index=[2, 3, 4])

In [28]: df2
Out[28]: 
   B  C
2  4  1
3  5  2
4  6  3

[3 rows x 2 columns]

In [29]: combined = df1.combine_first(df2)

以前的行为

In [1]: combined.dtypes
Out[2]:
A    float64
B    float64
C    float64
dtype: object

新行为

In [30]: combined.dtypes
Out[30]: 
A    float64
B      int64
C    float64
Length: 3, dtype: object

Groupby方法agg和Transform不再更改可调用对象的返回数据类型#

以前,这些方法 DataFrameGroupBy.aggregate()SeriesGroupBy.aggregate()DataFrameGroupBy.transform() ,以及 SeriesGroupBy.transform() 可能在参数设置为 func 是可调用的,可能会导致不良结果 (GH21240 )。如果结果是数值,并且转换回输入数据类型不会更改任何值,则会发生强制转换 np.allclose 。现在,这样的选角没有发生。

In [31]: df = pd.DataFrame({'key': [1, 1], 'a': [True, False], 'b': [True, True]})

In [32]: df
Out[32]: 
   key      a     b
0    1   True  True
1    1  False  True

[2 rows x 3 columns]

以前的行为

In [5]: df.groupby('key').agg(lambda x: x.sum())
Out[5]:
        a  b
key
1    True  2

新行为

In [33]: df.groupby('key').agg(lambda x: x.sum())
Out[33]: 
     a  b
key      
1    1  2

[1 rows x 2 columns]

float result for GroupBy.mean(), GroupBy.median(), and GroupBy.var()#

以前,根据输入值的不同,这些方法可能产生不同的数据类型。现在,这些方法将始终返回一个浮点数据类型。 (GH41137 )

In [34]: df = pd.DataFrame({'a': [True], 'b': [1], 'c': [1.0]})

以前的行为

In [5]: df.groupby(df.index).mean()
Out[5]:
        a  b    c
0    True  1  1.0

新行为

In [35]: df.groupby(df.index).mean()
Out[35]: 
     a    b    c
0  1.0  1.0  1.0

[1 rows x 3 columns]

使用设置值时尝试就地操作 lociloc#

使用设置整列时 lociloc ,Pandas将尝试将值插入到现有数据中,而不是创建一个全新的数组。

In [36]: df = pd.DataFrame(range(3), columns=["A"], dtype="float64")

In [37]: values = df.values

In [38]: new = np.array([5, 6, 7], dtype="int64")

In [39]: df.loc[[0, 1, 2], "A"] = new

在新的和旧的行为中, values 被覆盖,但在旧行为中, df["A"] 更改为 int64

以前的行为

In [1]: df.dtypes
Out[1]:
A    int64
dtype: object
In [2]: np.shares_memory(df["A"].values, new)
Out[2]: False
In [3]: np.shares_memory(df["A"].values, values)
Out[3]: False

在Pandas1.3.0中, df 继续与共享数据 values

新行为

In [40]: df.dtypes
Out[40]: 
A    float64
Length: 1, dtype: object

In [41]: np.shares_memory(df["A"], new)
Out[41]: False

In [42]: np.shares_memory(df["A"], values)
Out[42]: True

设置时切勿原地操作 frame[keys] = values#

使用设置多个列时 frame[keys] = values 新数组将替换这些键的先前存在的数组,这将 not 被覆盖 (GH39510 )。因此,这些列将保留 values ,从不强制转换为现有数组的数据类型。

In [43]: df = pd.DataFrame(range(3), columns=["A"], dtype="float64")

In [44]: df[["A"]] = 5

在过去的行为中, 5 被选为 float64 并插入到现有的阵列背衬中 df

以前的行为

In [1]: df.dtypes
Out[1]:
A    float64

在新的行为中,我们获得了一个新的数组,并保留了一个整数类型的 5

新行为

In [45]: df.dtypes
Out[45]: 
A    int64
Length: 1, dtype: object

设置为布尔级数的一致性投射#

Setting non-boolean values into a Series with dtype=bool now consistently casts to dtype=object (GH38709)

In [46]: orig = pd.Series([True, False])

In [47]: ser = orig.copy()

In [48]: ser.iloc[1] = np.nan

In [49]: ser2 = orig.copy()

In [50]: ser2.iloc[1] = 2.0

以前的行为

In [1]: ser
Out [1]:
0    1.0
1    NaN
dtype: float64

In [2]:ser2
Out [2]:
0    True
1     2.0
dtype: object

新行为

In [51]: ser
Out[51]: 
0    True
1     NaN
Length: 2, dtype: object

In [52]: ser2
Out[52]: 
0    True
1     2.0
Length: 2, dtype: object

GroupBy.Rolling不再返回值中的分组依据列#

GROUP-BY列现在将从 groupby.rolling 运营 (GH32262 )

In [53]: df = pd.DataFrame({"A": [1, 1, 2, 3], "B": [0, 1, 2, 3]})

In [54]: df
Out[54]: 
   A  B
0  1  0
1  1  1
2  2  2
3  3  3

[4 rows x 2 columns]

以前的行为

In [1]: df.groupby("A").rolling(2).sum()
Out[1]:
       A    B
A
1 0  NaN  NaN
1    2.0  1.0
2 2  NaN  NaN
3 3  NaN  NaN

新行为

In [55]: df.groupby("A").rolling(2).sum()
Out[55]: 
       B
A       
1 0  NaN
  1  1.0
2 2  NaN
3 3  NaN

[4 rows x 1 columns]

去除了滚动方差和标准差中的人为截断#

Rolling.std()Rolling.var() 将不再人为截断小于 ~1e-8~1e-15 分别降为零 (GH37051GH40448GH39872 )。

但是,现在当滚动到较大的值时,结果中可能存在浮点瑕疵。

In [56]: s = pd.Series([7, 5, 5, 5])

In [57]: s.rolling(3).var()
Out[57]: 
0         NaN
1         NaN
2    1.333333
3    0.000000
Length: 4, dtype: float64

使用多索引滚动的GroupBy.不再删除结果中的级别#

GroupBy.rolling() 将不再降低 DataFrame 使用一个 MultiIndex 在结果中。这可能会导致感觉到结果中的级别重复 MultiIndex ,但此更改恢复了1.1.3版中的行为 (GH38787GH38523 )。

In [58]: index = pd.MultiIndex.from_tuples([('idx1', 'idx2')], names=['label1', 'label2'])

In [59]: df = pd.DataFrame({'a': [1], 'b': [2]}, index=index)

In [60]: df
Out[60]: 
               a  b
label1 label2      
idx1   idx2    1  2

[1 rows x 2 columns]

以前的行为

In [1]: df.groupby('label1').rolling(1).sum()
Out[1]:
          a    b
label1
idx1    1.0  2.0

新行为

In [61]: df.groupby('label1').rolling(1).sum()
Out[61]: 
                        a    b
label1 label1 label2          
idx1   idx1   idx2    1.0  2.0

[1 rows x 2 columns]

向后不兼容的API更改#

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

更新了一些受支持的依赖项的最低版本。如果已安装,我们现在需要:

套餐

最低版本

必填项

变化

钱币

1.17.3

X

X

皮兹

2017.3

X

Python-Dateutil

2.7.3

X

瓶颈

1.2.1

数字快递

2.7.0

X

最热(Dev)

6.0

X

Mypy(开发人员)

0.812

X

安装工具

38.6.0

X

optional libraries 一般建议使用最新版本。下表列出了目前在整个Pandas发育过程中正在测试的每个库的最低版本。低于最低测试版本的可选库仍可运行,但不被视为受支持。

套餐

最低版本

变化

美味可口的汤

4.6.0

实木地板

0.4.0

X

FsSpec

0.7.4

Gcsf

0.6.0

Lxml

4.3.0

Matplotlib

2.2.3

Numba

0.46.0

OpenPyxl

3.0.0

X

绿箭侠

0.17.0

X

Pymysql

0.8.1

X

易燃物

3.5.1

S3FS

0.4.0

斯比

1.2.0

SQLALCHIZY

1.3.0

X

制表

0.8.7

X

XARRAY

0.12.0

Xlrd

1.2.0

Xlsx写入器

1.0.2

超大重量

1.3.0

Pandas-Gbq

0.12.0

看见 依赖项可选依赖项 想要更多。

其他API更改#

  • 部分初始化 CategoricalDtype 对象(即具有 categories=None )将不再等同于完全初始化的数据类型对象 (GH38516 )

  • 访问 _constructor_expanddim 在一个 DataFrame_constructor_sliced 在一个 Series 现在引发一个 AttributeError 。以前是 NotImplementedError 被提了出来 (GH38782 )

  • Added new engine and **engine_kwargs parameters to DataFrame.to_sql() to support other future "SQL engines". Currently we still only use SQLAlchemy under the hood, but more engines are planned to be supported such as turbodbc (GH36893)

  • 删除冗余 freq 从… PeriodIndex 字符串表示法 (GH41653 )

  • ExtensionDtype.construct_array_type() 现在是必需的方法,而不是 ExtensionDtype 子类 (GH24860 )

  • Calling hash on non-hashable pandas objects will now raise TypeError with the built-in error message (e.g. unhashable type: 'Series'). Previously it would raise a custom message such as 'Series' objects are mutable, thus they cannot be hashed. Furthermore, isinstance(<Series>, abc.collections.Hashable) will now return False (GH40013)

  • Styler.from_custom_template() 现在有两个新的模板名称参数,并删除了旧的 name ,因为为了更好地解析而引入了模板继承 (GH42053 )。还需要对Styler属性进行子类化修改。

建房#

  • 中的文档 .pptx.pdf 格式不再包含在控制盘或源代码分发中。 (GH30741 )

不推荐使用#

不建议在DataFrame Reductions和DataFrameGroupBy操作中删除讨厌的列#

调用减价(例如 .min.max.sum )上 DataFrame 使用 numeric_only=None (缺省设置),其中减少会引发 TypeError 被默默地忽略并从结果中删除。

此行为已弃用。在未来的版本中, TypeError 将引发,并且用户在调用该函数之前将只需要选择有效列。

例如:

In [62]: df = pd.DataFrame({"A": [1, 2, 3, 4], "B": pd.date_range("2016-01-01", periods=4)})

In [63]: df
Out[63]: 
   A          B
0  1 2016-01-01
1  2 2016-01-02
2  3 2016-01-03
3  4 2016-01-04

[4 rows x 2 columns]

旧行为

In [3]: df.prod()
Out[3]:
Out[3]:
A    24
dtype: int64

未来行为

In [4]: df.prod()
...
TypeError: 'DatetimeArray' does not implement reduction 'prod'

In [5]: df[["A"]].prod()
Out[5]:
A    24
dtype: int64

同样,在将函数应用于 DataFrameGroupBy ,函数在其上引发的列 TypeError 当前被静默忽略并从结果中删除。

此行为已弃用。在未来的版本中, TypeError 将引发,并且用户在调用该函数之前将只需要选择有效列。

例如:

In [64]: df = pd.DataFrame({"A": [1, 2, 3, 4], "B": pd.date_range("2016-01-01", periods=4)})

In [65]: gb = df.groupby([1, 1, 2, 2])

旧行为

In [4]: gb.prod(numeric_only=False)
Out[4]:
A
1   2
2  12

未来行为

In [5]: gb.prod(numeric_only=False)
...
TypeError: datetime64 type does not support prod operations

In [6]: gb[["A"]].prod(numeric_only=False)
Out[6]:
    A
1   2
2  12

其他不推荐使用的词#

性能改进#

错误修复#

直截了当的#

  • 窃听 CategoricalIndex 错误地未能筹集 TypeError 在传递标量数据时 (GH38614 )

  • 窃听 CategoricalIndex.reindex 失败时,如果 Index Passed不是绝对的,但其值是类别中的所有标签 (GH28690 )

  • Bug where constructing a Categorical from an object-dtype array of date objects did not round-trip correctly with astype (GH38552)

  • Bug in constructing a DataFrame from an ndarray and a CategoricalDtype (GH38857)

  • Bug in setting categorical values into an object-dtype column in a DataFrame (GH39136)

  • Bug in DataFrame.reindex() was raising an IndexError when the new index contained duplicates and the old index was a CategoricalIndex (GH38906)

  • 窃听 Categorical.fillna() 使用类似元组的类别引发 NotImplementedError 而不是 ValueError 使用非类别元组填充时 (GH41914 )

类似日期的#

Timedelta#

  • Bug in constructing Timedelta from np.timedelta64 objects with non-nanosecond units that are out of bounds for timedelta64[ns] (GH38965)

  • 在构造一个 TimedeltaIndex 错误地接受 np.datetime64("NaT") 对象 (GH39462 )

  • 建筑中的错误 Timedelta 从只有符号而没有数字的输入字符串引发错误失败 (GH39710 )

  • Bug in TimedeltaIndex and to_timedelta() failing to raise when passed non-nanosecond timedelta64 arrays that overflow when converting to timedelta64[ns] (GH40008)

时区#

  • 不同版本中的错误 tzinfo 表示UTC的对象不被视为等效 (GH39216 )

  • 窃听 dateutil.tz.gettz("UTC") 不被认为等同于代表tzinfos的其他UTC (GH39276 )

数字#

转换#

  • 窃听 Series.to_dict() 使用 orient='records' 现在返回Python本机类型 (GH25969 )

  • 窃听 Series.view()Index.view() 当在类DateTime之间进行转换时 (datetime64[ns]datetime64[ns, tz]timedelta64period )数据类型 (GH39788 )

  • 在创建一个 DataFrame 从一个空虚的 np.recarray 不保留原始数据类型 (GH40121 )

  • Bug in DataFrame failing to raise a TypeError when constructing from a frozenset (GH40163)

  • 窃听 Index 构造静默忽略已传递的 dtype 当数据无法转换为该数据类型时 (GH21311 )

  • Bug in StringArray.astype() falling back to NumPy and raising when converting to dtype='categorical' (GH40450)

  • 窃听 factorize() 其中,当给定数值NumPy dtype小于int64、uint64和flat64的数组时,唯一值不保留其原始数据类型 (GH41132 )

  • 窃听 DataFrame 使用包含类似数组的 ExtensionDtypecopy=True 未能复制副本 (GH38939 )

  • 窃听 qcut() 取数时出现误差 Float64DType 作为输入 (GH40730 )

  • 窃听 DataFrameSeries 使用以下工具进行施工 datetime64[ns] 数据和 dtype=object 导致 datetime 对象而不是 Timestamp 对象 (GH41599 )

  • 窃听 DataFrameSeries 使用以下工具进行施工 timedelta64[ns] 数据和 dtype=object 导致 np.timedelta64 对象而不是 Timedelta 对象 (GH41599 )

  • 窃听 DataFrame 在给定二维对象-dtype时构造 np.ndarrayPeriodInterval 未能强制转换为的对象 PeriodDtypeIntervalDtype ,分别 (GH41812 )

  • Bug in constructing a Series from a list and a PandasDtype (GH39357)

  • 在创建一个 Series 从一个 range 对象,该对象不在 int64 数据类型 (GH30173 )

  • 在创建一个 Series 从一个 dict 具有全元组键和 Index 这需要重新编制索引 (GH41707 )

  • 窃听 infer_dtype() 无法识别具有句点数据类型的系列、索引或数组 (GH23553 )

  • 窃听 infer_dtype() 引发常规错误 ExtensionArray 物体。它现在将返回 "unknown-array" 与其提高 (GH37367 )

  • 窃听 DataFrame.convert_dtypes() 错误地引发了 ValueError 在空的DataFrame上调用时 (GH40393 )

字符串#

间隔#

  • Bug in IntervalIndex.intersection() and IntervalIndex.symmetric_difference() always returning object-dtype when operating with CategoricalIndex (GH38653, GH38741)

  • 窃听 IntervalIndex.intersection() 属性中的至少一个返回重复项 Index 对象具有存在于其他对象中的重复项 (GH38743 )

  • IntervalIndex.union()IntervalIndex.intersection()IntervalIndex.difference() ,以及 IntervalIndex.symmetric_difference() 现在强制转换为适当的dtype,而不是引发 TypeError 当与其他人一起操作时 IntervalIndex 具有不兼容的数据类型 (GH39267 )

  • PeriodIndex.union()PeriodIndex.intersection()PeriodIndex.symmetric_difference()PeriodIndex.difference() 现在强制转换为对象dtype,而不是引发 IncompatibleFrequency 当与其他人一起操作时 PeriodIndex 具有不兼容的数据类型 (GH39306 )

  • 窃听 IntervalIndex.is_monotonic()IntervalIndex.get_loc()IntervalIndex.get_indexer_for() ,以及 IntervalIndex.__contains__() 当存在NA值时 (GH41831 )

标引#

  • Bug in Index.union() and MultiIndex.union() dropping duplicate Index values when Index was not monotonic or sort was set to False (GH36289, GH31326, GH40862)

  • 窃听 CategoricalIndex.get_indexer() 未能筹集到 InvalidIndexError 非唯一时 (GH38372 )

  • 窃听 IntervalIndex.get_indexer() 什么时候 targetCategoricalDtype 并且索引和目标都包含NA值 (GH41934 )

  • 窃听 Series.loc() 提高一名 ValueError 使用布尔列表过滤输入时,要设置的值是具有较低维度的列表 (GH20438 )

  • 将许多新列插入到 DataFrame 导致不正确的后续索引行为 (GH38380 )

  • 窃听 DataFrame.__setitem__() 提高一名 ValueError 将多个值设置为重复列时 (GH15695 )

  • 窃听 DataFrame.loc()Series.loc()DataFrame.__getitem__()Series.__getitem__() 为非单调返回不正确的元素 DatetimeIndex 对于字符串切片 (GH33146 )

  • Bug in DataFrame.reindex() and Series.reindex() with timezone aware indexes raising a TypeError for method="ffill" and method="bfill" and specified tolerance (GH38566)

  • 窃听 DataFrame.reindex() 使用 datetime64[ns]timedelta64[ns] 属性时错误地转换为整数 fill_value 需要强制转换为对象数据类型 (GH39755 )

  • 窃听 DataFrame.__setitem__() 提高一名 ValueError 当设置在空的 DataFrame 使用指定的列和非空值 DataFrame 价值 (GH38831 )

  • 窃听 DataFrame.loc.__setitem__() 提高一名 ValueError 在唯一列上操作时,如果 DataFrame 具有重复的列 (GH38521 )

  • 窃听 DataFrame.iloc.__setitem__()DataFrame.loc.__setitem__() 在使用字典值进行设置时使用混合数据类型 (GH38335 )

  • 窃听 Series.loc.__setitem__()DataFrame.loc.__setitem__() 加薪 KeyError 当提供布尔生成器时 (GH39614 )

  • 窃听 Series.iloc()DataFrame.iloc() 提高一名 KeyError 当提供发电机时 (GH39614 )

  • 窃听 DataFrame.__setitem__() 而不是引发 ValueError 当右侧是一个 DataFrame 列数错误 (GH38604 )

  • 窃听 Series.__setitem__() 提高一名 ValueError 在设置 Series 使用标量索引器 (GH38303 )

  • 窃听 DataFrame.loc() 正在降低 MultiIndexDataFrame 用作输入的只有一行 (GH10521 )

  • 窃听 DataFrame.__getitem__()Series.__getitem__() 总是在提高 KeyError 当使用现有字符串进行切片时, Index 有几毫秒 (GH33589 )

  • 设置中存在错误 timedelta64datetime64 将值转换为数字 Series 无法强制转换为对象数据类型 (GH39086GH39619 )

  • 设置中存在错误 Interval 值转换为 SeriesDataFrame 不匹配的 IntervalDtype 错误地将新值转换为现有的dtype (GH39120 )

  • 设置中存在错误 datetime64 值转换为 Series 使用INTEGER-DTYPE错误地将DateTime64值转换为整数 (GH39266 )

  • 设置中存在错误 np.datetime64("NaT") 变成一个 Series 使用 Datetime64TZDtype 错误地将时区朴素值视为时区感知 (GH39769 )

  • Bug in Index.get_loc() not raising KeyError when key=NaN and method is specified but NaN is not in the Index (GH39382)

  • 窃听 DatetimeIndex.insert() 当插入时 np.datetime64("NaT") 错误地将时区朴素值视为时区感知索引 (GH39769 )

  • 错误地提高了 Index.insert() 设置不能保存在现有 frame.columns ,或在 Series.reset_index()DataFrame.reset_index() 而不是强制转换为兼容的数据类型 (GH39068 )

  • 窃听 RangeIndex.append() 长度为1的单个对象连接不正确 (GH39401 )

  • Bug in RangeIndex.astype() where when converting to CategoricalIndex, the categories became a Int64Index instead of a RangeIndex (GH41263)

  • 设置中存在错误 numpy.timedelta64 值转换为对象数据类型 Series 使用布尔索引器 (GH39488 )

  • 将数值设置为布尔型时出错 Series 使用 atiat 无法强制转换为对象数据类型 (GH39582 )

  • 窃听 DataFrame.__setitem__()DataFrame.iloc.__setitem__() 加薪 ValueError 尝试使用行切片进行索引并将列表设置为值时 (GH40440 )

  • 窃听 DataFrame.loc() 不是募捐 KeyError 在以下位置找不到密钥 MultiIndex 并且没有完全详细说明这些水平 (GH41170 )

  • 窃听 DataFrame.loc.__setitem__() 当扩展轴中的索引包含重复项时,设置WITH-EXPAND错误提升 (GH40096 )

  • 窃听 DataFrame.loc.__getitem__() 使用 MultiIndex 当至少一个索引列具有FLOAT数据类型并且检索标量时,强制转换为FLOAT (GH41369 )

  • 窃听 DataFrame.loc() 非布尔索引元素不正确匹配 (GH20432 )

  • 使用索引时出现错误 np.nan 在一个 SeriesDataFrame 使用一个 CategoricalIndex 错误地提高 KeyError 什么时候 np.nan 钥匙已存在 (GH41933 )

  • Bug in Series.__delitem__() with ExtensionDtype incorrectly casting to ndarray (GH40386)

  • 窃听 DataFrame.at() 使用一个 CategoricalIndex 传递整型键时返回错误结果 (GH41846 )

  • 窃听 DataFrame.loc() 返回一个 MultiIndex 如果索引器有重复项,则顺序错误 (GH40978 )

  • Bug in DataFrame.__setitem__() raising a TypeError when using a str subclass as the column name with a DatetimeIndex (GH37366)

  • Bug in PeriodIndex.get_loc() failing to raise a KeyError when given a Period with a mismatched freq (GH41670)

  • 虫虫 .loc.__getitem__ 使用一个 UInt64Index 和负整数键提升 OverflowError 而不是 KeyError 在某些情况下,在其他情况下绕回到正整数 (GH41777 )

  • 窃听 Index.get_indexer() 未能筹集到 ValueError 在某些情况下,无效 methodlimit ,或 tolerance 论据 (GH41918 )

  • Bug when slicing a Series or DataFrame with a TimedeltaIndex when passing an invalid string raising ValueError instead of a TypeError (GH41821)

  • Bug in Index constructor sometimes silently ignoring a specified dtype (GH38879)

  • Index.where() behavior now mirrors Index.putmask() behavior, i.e. index.where(mask, other) matches index.putmask(~mask, other) (GH39412)

丢失#

MultiIndex#

  • 窃听 DataFrame.drop() 提高一名 TypeErrorMultiIndex 不是唯一的,并且 level 未提供 (GH36293 )

  • 窃听 MultiIndex.intersection() 复制 NaN 在结果中 (GH38623 )

  • 窃听 MultiIndex.equals() 返回错误 TrueMultiIndex 包含 NaN 即使它们的顺序不同 (GH38439 )

  • Bug in MultiIndex.intersection() always returning an empty result when intersecting with CategoricalIndex (GH38653)

  • 窃听 MultiIndex.difference() 错误地提高 TypeError 当索引包含不可排序的条目时 (GH41915 )

  • 窃听 MultiIndex.reindex() 提高一名 ValueError 在空白处使用时 MultiIndex 并且只对特定级别进行索引 (GH41170 )

  • Bug in MultiIndex.reindex() raising TypeError when reindexing against a flat Index (GH41707)

I/O#

期间#

  • 比较 Period 对象或 IndexSeries ,或 DataFrame 不匹配的 PeriodDtype 现在的行为与其他不匹配的类型比较一样,返回 False 对于平等的人来说, True 对于不平等,并提高 TypeError 对于不平等检查 (GH39274 )

标绘#

  • 窃听 plotting.scatter_matrix() 在2d时引发 ax 传递的参数 (GH16253 )

  • 当Matplotlib的 constrained_layout 已启用 (GH25261 )

  • 窃听 DataFrame.plot() 如果重复调用函数并使用某些调用,则在图例中显示错误的颜色 yerr 而其他人则没有 (GH39522 )

  • Bug in DataFrame.plot() was showing the wrong colors in the legend if the function was called repeatedly and some calls used secondary_y and others use legend=False (GH40044)

  • 窃听 DataFrame.plot.box() 什么时候 dark_background 已选择主题,绘图的大写字母或最小/最大值标记不可见 (GH40769 )

分组/重采样/滚动#

重塑#

稀疏#

  • Bug in DataFrame.sparse.to_coo() raising a KeyError with columns that are a numeric Index without a 0 (GH18414)

  • 窃听 SparseArray.astype() 使用 copy=False 从整型数据类型转换为浮点型数据类型时产生错误的结果 (GH34456 )

  • 窃听 SparseArray.max()SparseArray.min() 将始终返回空结果 (GH40921 )

ExtensionArray#

造型师#

  • 窃听 Styler 其中 subset 对于某些有效的多索引切片,方法中的参数引发错误 (GH33562 )

  • Styler 呈现的HTML输出进行了细微更改,以支持w3良好的代码标准 (GH39626 )

  • 窃听 Styler 其中呈现的HTML缺少某些标题单元格的列类标识符 (GH39716 )

  • 窃听 Styler.background_gradient() 未正确确定文本颜色的位置 (GH39888 )

  • 窃听 Styler.set_table_styles() 的css-选择器中的多个元素 table_styles 参数未正确添加 (GH34061 )

  • 窃听 Styler 从Jupyter复制时丢弃了左上角单元格和未对齐的标题 (GH12147 )

  • 窃听 Styler.where 哪里 kwargs 未传递给适用的可调用对象 (GH40845 )

  • 窃听 Styler 导致CSS在多个渲染上复制 (GH39395GH40334 )

其他#

贡献者#

共有251人为此次发布贡献了补丁。名字中带有“+”的人第一次贡献了一个补丁。

  • Abhishek R +

  • Ada Draginda

  • Adam J. Stewart

  • Adam Turner +

  • Aidan Feldman +

  • Ajitesh Singh +

  • Akshat Jain +

  • Albert Villanova del Moral

  • Alexandre Prince-Levasseur +

  • Andrew Hawyrluk +

  • Andrew Wieteska

  • AnglinaBhambra +

  • Ankush Dua +

  • Anna Daglis

  • Ashlan Parker +

  • Ashwani +

  • Avinash Pancham

  • Ayushman Kumar +

  • BeanNan

  • Benoît Vinot

  • Bharat Raghunathan

  • Bijay Regmi +

  • Bobin Mathew +

  • Bogdan Pilyavets +

  • Brian Hulette +

  • Brian Sun +

  • Brock +

  • Bryan Cutler

  • Caleb +

  • Calvin Ho +

  • Chathura Widanage +

  • Chinmay Rane +

  • Chris Lynch

  • Chris Withers

  • Christos Petropoulos

  • Corentin Girard +

  • DaPy15 +

  • Damodara Puddu +

  • Daniel Hrisca

  • Daniel Saxton

  • DanielFEvans

  • Dare Adewumi +

  • Dave Willmer

  • David Schlachter +

  • David-dmh +

  • Deepang Raval +

  • Doris Lee +

  • Dr. Jan-Philip Gehrcke +

  • DriesS +

  • Dylan Percy

  • Erfan Nariman

  • Eric Leung

  • EricLeer +

  • Eve

  • Fangchen Li

  • Felix Divo

  • Florian Jetter

  • Fred Reiss

  • GFJ138 +

  • Gaurav Sheni +

  • Geoffrey B. Eisenbarth +

  • Gesa Stupperich +

  • Griffin Ansel +

  • Gustavo C. Maciel +

  • Heidi +

  • Henry +

  • Hung-Yi Wu +

  • Ian Ozsvald +

  • Irv Lustig

  • Isaac Chung +

  • Isaac Virshup

  • JHM Darbyshire (MBP) +

  • JHM Darbyshire (iMac) +

  • Jack Liu +

  • James Lamb +

  • Jeet Parekh

  • Jeff Reback

  • Jiezheng2018 +

  • Jody Klymak

  • Johan Kåhrström +

  • John McGuigan

  • Joris Van den Bossche

  • Jose

  • JoseNavy

  • Josh Dimarsky

  • Josh Friedlander

  • Joshua Klein +

  • Julia Signell

  • Julian Schnitzler +

  • Kaiqi Dong

  • Kasim Panjri +

  • Katie Smith +

  • Kelly +

  • Kenil +

  • Keppler, Kyle +

  • Kevin Sheppard

  • Khor Chean Wei +

  • Kiley Hewitt +

  • Larry Wong +

  • Lightyears +

  • Lucas Holtz +

  • Lucas Rodés-Guirao

  • Lucky Sivagurunathan +

  • Luis Pinto

  • Maciej Kos +

  • Marc Garcia

  • Marco Edward Gorelli +

  • Marco Gorelli

  • MarcoGorelli +

  • Mark Graham

  • Martin Dengler +

  • Martin Grigorov +

  • Marty Rudolf +

  • Matt Roeschke

  • Matthew Roeschke

  • Matthew Zeitlin

  • Max Bolingbroke

  • Maxim Ivanov

  • Maxim Kupfer +

  • Mayur +

  • MeeseeksMachine

  • Micael Jarniac

  • Michael Hsieh +

  • Michel de Ruiter +

  • Mike Roberts +

  • Miroslav Šedivý

  • Mohammad Jafar Mashhadi

  • Morisa Manzella +

  • Mortada Mehyar

  • Muktan +

  • Naveen Agrawal +

  • Noah

  • Nofar Mishraki +

  • Oleh Kozynets

  • Olga Matoula +

  • Oli +

  • Omar Afifi

  • Omer Ozarslan +

  • Owen Lamont +

  • Ozan Öğreden +

  • Pandas Development Team

  • Paolo Lammens

  • Parfait Gasana +

  • Patrick Hoefler

  • Paul McCarthy +

  • Paulo S. Costa +

  • Pav A

  • Peter

  • Pradyumna Rahul +

  • Punitvara +

  • QP Hou +

  • Rahul Chauhan

  • Rahul Sathanapalli

  • Richard Shadrach

  • Robert Bradshaw

  • Robin to Roxel

  • Rohit Gupta

  • Sam Purkis +

  • Samuel GIFFARD +

  • Sean M. Law +

  • Shahar Naveh +

  • ShaharNaveh +

  • Shiv Gupta +

  • Shrey Dixit +

  • Shudong Yang +

  • Simon Boehm +

  • Simon Hawkins

  • Sioned Baker +

  • Stefan Mejlgaard +

  • Steven Pitman +

  • Steven Schaerer +

  • Stéphane Guillou +

  • TLouf +

  • Tegar D Pratama +

  • Terji Petersen

  • Theodoros Nikolaou +

  • Thomas Dickson

  • Thomas Li

  • Thomas Smith

  • Thomas Yu +

  • ThomasBlauthQC +

  • Tim Hoffmann

  • Tom Augspurger

  • Torsten Wörtwein

  • Tyler Reddy

  • UrielMaD

  • Uwe L. Korn

  • Venaturum +

  • VirosaLi

  • Vladimir Podolskiy

  • Vyom Pathak +

  • WANG Aiyong

  • Waltteri Koskinen +

  • Wenjun Si +

  • William Ayd

  • Yeshwanth N +

  • Yuanhao Geng

  • Zito Relova +

  • aflah02 +

  • arredond +

  • attack68

  • cdknox +

  • chinggg +

  • fathomer +

  • ftrihardjo +

  • github-actions[bot] +

  • gunjan-solanki +

  • guru kiran

  • hasan-yaman

  • i-aki-y +

  • jbrockmendel

  • jmholzer +

  • jordi-crespo +

  • jotasi +

  • jreback

  • juliansmidek +

  • kylekeppler

  • lrepiton +

  • lucasrodes

  • maroth96 +

  • mikeronayne +

  • mlondschien

  • moink +

  • morrme

  • mschmookler +

  • mzeitlin11

  • na2 +

  • nofarmishraki +

  • partev

  • patrick

  • ptype

  • realead

  • rhshadrach

  • rlukevie +

  • rosagold +

  • saucoide +

  • sdementen +

  • shawnbrown

  • sstiijn +

  • stphnlyd +

  • sukriti1 +

  • taytzehao

  • theOehrly +

  • theodorju +

  • thordisstella +

  • tonyyyyip +

  • tsinggggg +

  • tushushu +

  • vangorade +

  • vladu +

  • wertha +