0.24.0 中的新增功能(2019 年 1 月 25 日)#

警告

0.24.x 系列版本将是最后一个支持 Python 2 的版本。未来的功能版本将仅支持 Python 3。有关更多详细信息,请参阅删除 Python 2.7 。

这是 0.23.4 的主要版本,包括大量 API 更改、新功能、增强功能和性能改进以及大量错误修复。

亮点包括:

更新前请检查API 更改弃用。

这些是 pandas 0.24.0 中的变化。请参阅发行说明以获取完整的变更日志,包括其他版本的 pandas。

增强功能#

可选整数 NA 支持#

pandas 已经获得了保存缺失值的整数数据类型的能力。这个长期请求的功能是通过使用扩展类型来实现的。

笔记

IntegerArray 目前处于实验阶段。其 API 或实现可能会在没有警告的情况下发生更改。

我们可以Series用指定的 dtype 构造一个。 dtype 字符串Int64是 pandas ExtensionDtype。使用传统的缺失值标记指定列表或数组np.nan将推断为整数数据类型。的显示Series还将使用 来NaN指示字符串输出中的缺失值。 (GH 20700GH 20747GH 22441GH 21789GH 22346

In [1]: s = pd.Series([1, 2, np.nan], dtype='Int64')

In [2]: s
Out[2]: 
0       1
1       2
2    <NA>
Length: 3, dtype: Int64

对这些数据类型的操作将NaN像其他 pandas 操作一样传播。

# arithmetic
In [3]: s + 1
Out[3]: 
0       2
1       3
2    <NA>
Length: 3, dtype: Int64

# comparison
In [4]: s == 1
Out[4]: 
0     True
1    False
2     <NA>
Length: 3, dtype: boolean

# indexing
In [5]: s.iloc[1:3]
Out[5]: 
1       2
2    <NA>
Length: 2, dtype: Int64

# operate with other dtypes
In [6]: s + s.iloc[1:3].astype('Int8')
Out[6]: 
0    <NA>
1       4
2    <NA>
Length: 3, dtype: Int64

# coerce when needed
In [7]: s + 0.01
Out[7]: 
0    1.01
1    2.01
2    <NA>
Length: 3, dtype: Float64

这些数据类型可以作为DataFrame.

In [8]: df = pd.DataFrame({'A': s, 'B': [1, 1, 3], 'C': list('aab')})

In [9]: df
Out[9]: 
      A  B  C
0     1  1  a
1     2  1  a
2  <NA>  3  b

[3 rows x 3 columns]

In [10]: df.dtypes
Out[10]: 
A     Int64
B     int64
C    object
Length: 3, dtype: object

这些数据类型可以合并、重塑和转换。

In [11]: pd.concat([df[['A']], df[['B', 'C']]], axis=1).dtypes
Out[11]: 
A     Int64
B     int64
C    object
Length: 3, dtype: object

In [12]: df['A'].astype(float)
Out[12]: 
0    1.0
1    2.0
2    NaN
Name: A, Length: 3, dtype: float64

工作归约和groupby等操作sum

In [13]: df.sum()
Out[13]: 
A      3
B      5
C    aab
Length: 3, dtype: object

In [14]: df.groupby('B').A.sum()
Out[14]: 
B
1    3
3    0
Name: A, Length: 2, dtype: Int64

警告

Integer NA 支持当前使用大写的 dtype 版本,例如Int8与传统的int8.这可能会在未来发生变化。

有关详细信息,请参阅可为空整数数据类型

访问系列或索引中的值#

Series.array并已添加用于提取支持 a或 的Index.array数组 。 (GH 19954GH 23623SeriesIndex

In [15]: idx = pd.period_range('2000', periods=4)

In [16]: idx.array
Out[16]: 
<PeriodArray>
['2000-01-01', '2000-01-02', '2000-01-03', '2000-01-04']
Length: 4, dtype: period[D]

In [17]: pd.Series(idx).array
Out[17]: 
<PeriodArray>
['2000-01-01', '2000-01-02', '2000-01-03', '2000-01-04']
Length: 4, dtype: period[D]

从历史上看,这可以通过 来完成series.values,但 .values不清楚返回的值是实际数组、它的某种转换还是 pandas 自定义数组之一(例如 Categorical)。例如,使用PeriodIndex,.values每次都会生成一个新的 ndarray 周期对象。

In [18]: idx.values
Out[18]: 
array([Period('2000-01-01', 'D'), Period('2000-01-02', 'D'),
       Period('2000-01-03', 'D'), Period('2000-01-04', 'D')], dtype=object)

In [19]: id(idx.values)
Out[19]: 140678188264656

In [20]: id(idx.values)
Out[20]: 140678188258896

如果您需要实际的 NumPy 数组,请使用Series.to_numpy()Index.to_numpy()

In [21]: idx.to_numpy()
Out[21]: 
array([Period('2000-01-01', 'D'), Period('2000-01-02', 'D'),
       Period('2000-01-03', 'D'), Period('2000-01-04', 'D')], dtype=object)

In [22]: pd.Series(idx).to_numpy()
Out[22]: 
array([Period('2000-01-01', 'D'), Period('2000-01-02', 'D'),
       Period('2000-01-03', 'D'), Period('2000-01-04', 'D')], dtype=object)

对于普通 NumPy 数组支持的系列和索引,Series.array将返回一个新的arrays.PandasArray,它是 numpy.ndarray.PandasArray本身并不是特别有用,但它确实提供了与 pandas 或第三方库定义的任何扩展数组相同的接口。

In [23]: ser = pd.Series([1, 2, 3])

In [24]: ser.array
Out[24]: 
<NumpyExtensionArray>
[1, 2, 3]
Length: 3, dtype: int64

In [25]: ser.to_numpy()
Out[25]: array([1, 2, 3])

我们尚未删除或弃用Series.valuesor DataFrame.values,但我们强烈建议使用.arrayor.to_numpy()代替。

有关更多信息,请参阅数据类型属性以及基础数据

pandas.array:创建数组的新顶级方法#

array()添加了一个新的顶级方法来创建一维数组( GH 22860)。这可用于创建任何扩展数组,包括由第 3 方库注册的扩展数组。有关扩展数组的更多信息,请参阅dtypes 文档。

In [26]: pd.array([1, 2, np.nan], dtype='Int64')
Out[26]: 
<IntegerArray>
[1, 2, <NA>]
Length: 3, dtype: Int64

In [27]: pd.array(['a', 'b', 'c'], dtype='category')
Out[27]: 
['a', 'b', 'c']
Categories (3, object): ['a', 'b', 'c']

传递没有专用扩展类型(例如浮点数、整数等)的数据将返回一个新的,它只是满足 pandas 扩展数组接口的arrays.PandasArraya 的薄(非复制)包装器。numpy.ndarray

In [28]: pd.array([1, 2, 3])
Out[28]: 
<IntegerArray>
[1, 2, 3]
Length: 3, dtype: Int64

就其本身而言, aPandasArray并不是一个非常有用的对象。但是,如果您需要编写适用于任何通用的低级代码 ExtensionArray,则PandasArray 可以满足该需求。

请注意,默认情况下,如果未dtype指定,则从数据推断返回数组的数据类型。特别要注意的是,第一个示例 将返回一个浮点数组,因为 是一个浮点数。[1, 2, np.nan]NaN

In [29]: pd.array([1, 2, np.nan])
Out[29]: 
<IntegerArray>
[1, 2, <NA>]
Length: 3, dtype: Int64

在 Series 和 DataFrame 中存储间隔和周期数据#

Interval除了之前的 a 等(GH 19453GH 22862)之外,数据Period现在还可以存储在 aSeries或中。DataFrameIntervalIndexPeriodIndex

In [30]: ser = pd.Series(pd.interval_range(0, 5))

In [31]: ser
Out[31]: 
0    (0, 1]
1    (1, 2]
2    (2, 3]
3    (3, 4]
4    (4, 5]
Length: 5, dtype: interval

In [32]: ser.dtype
Out[32]: interval[int64, right]

对于经期:

In [33]: pser = pd.Series(pd.period_range("2000", freq="D", periods=5))

In [34]: pser
Out[34]: 
0    2000-01-01
1    2000-01-02
2    2000-01-03
3    2000-01-04
4    2000-01-05
Length: 5, dtype: period[D]

In [35]: pser.dtype
Out[35]: period[D]

以前,这些将被转换为具有对象数据类型的 NumPy 数组。一般来说,在 aSeries或 a 列中存储间隔或周期数组时,这应该会带来更好的性能DataFrame

用于Series.array从 中提取间隔或周期的基础数组Series

In [36]: ser.array
Out[36]: 
<IntervalArray>
[(0, 1], (1, 2], (2, 3], (3, 4], (4, 5]]
Length: 5, dtype: interval[int64, right]

In [37]: pser.array
Out[37]: 
<PeriodArray>
['2000-01-01', '2000-01-02', '2000-01-03', '2000-01-04', '2000-01-05']
Length: 5, dtype: period[D]

arrays.IntervalArray它们返回or的实例arrays.PeriodArray,即支持间隔和周期数据的新扩展数组。

警告

为了向后兼容,Series.values继续返回 Interval 和 period 数据的 NumPy 对象数组。Series.array当您需要存储在 中的数据数组 Series以及Series.to_numpy()当您知道需要 NumPy 数组时,我们建议使用。

有关更多信息,请参阅数据类型属性以及基础数据

连接两个多索引#

DataFrame.merge()现在DataFrame.join()可用于连接Dataframe重叠索引级别上的多索引实例 ( GH 6360 )

请参阅合并、联接和连接文档部分。

In [38]: index_left = pd.MultiIndex.from_tuples([('K0', 'X0'), ('K0', 'X1'),
   ....:                                        ('K1', 'X2')],
   ....:                                        names=['key', 'X'])
   ....: 

In [39]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
   ....:                      'B': ['B0', 'B1', 'B2']}, index=index_left)
   ....: 

In [40]: index_right = pd.MultiIndex.from_tuples([('K0', 'Y0'), ('K1', 'Y1'),
   ....:                                         ('K2', 'Y2'), ('K2', 'Y3')],
   ....:                                         names=['key', 'Y'])
   ....: 

In [41]: right = pd.DataFrame({'C': ['C0', 'C1', 'C2', 'C3'],
   ....:                       'D': ['D0', 'D1', 'D2', 'D3']}, index=index_right)
   ....: 

In [42]: left.join(right)
Out[42]: 
            A   B   C   D
key X  Y                 
K0  X0 Y0  A0  B0  C0  D0
    X1 Y0  A1  B1  C0  D0
K1  X2 Y1  A2  B2  C1  D1

[3 rows x 4 columns]

对于早期版本,可以使用以下命令完成此操作。

In [43]: pd.merge(left.reset_index(), right.reset_index(),
   ....:          on=['key'], how='inner').set_index(['key', 'X', 'Y'])
   ....: 
Out[43]: 
            A   B   C   D
key X  Y                 
K0  X0 Y0  A0  B0  C0  D0
    X1 Y0  A1  B1  C0  D0
K1  X2 Y1  A2  B2  C1  D1

[3 rows x 4 columns]

功能read_html增强#

read_html()先前被忽略的colspan属性rowspan。现在它理解它们,将它们视为具有相同值的单元序列。 (GH 17054

In [44]: from io import StringIO

In [45]: result = pd.read_html(StringIO("""
   ....:   <table>
   ....:     <thead>
   ....:       <tr>
   ....:         <th>A</th><th>B</th><th>C</th>
   ....:       </tr>
   ....:     </thead>
   ....:     <tbody>
   ....:       <tr>
   ....:         <td colspan="2">1</td><td>2</td>
   ....:       </tr>
   ....:     </tbody>
   ....:   </table>"""))
   ....: 

以前的行为

In [13]: result
Out [13]:
[   A  B   C
 0  1  2 NaN]

新行为

In [46]: result
Out[46]: 
[   A  B  C
 0  1  1  2
 
 [1 rows x 3 columns]]

Styler.pipe()方法#

班级Styler获得了 pipe()方法。这提供了一种应用用户预定义样式功能的便捷方法,并且可以帮助减少在笔记本中重复使用 DataFrame 样式功能时的“样板文件”。 (GH 23229

In [47]: df = pd.DataFrame({'N': [1250, 1500, 1750], 'X': [0.25, 0.35, 0.50]})

In [48]: def format_and_align(styler):
   ....:     return (styler.format({'N': '{:,}', 'X': '{:.1%}'})
   ....:                   .set_properties(**{'text-align': 'right'}))
   ....: 

In [49]: df.style.pipe(format_and_align).set_caption('Summary of results.')
Out[49]: <pandas.io.formats.style.Styler at 0x7ff231a272e0>

pandas 中的其他类已经存在类似的方法,包括DataFrame.pipe()GroupBy.pipe()Resampler.pipe()

重命名 MultiIndex 中的名称#

DataFrame.rename_axis()现在支持indexcolumns论证并Series.rename_axis()支持index论证(GH 19978)。

此更改允许传递字典,以便MultiIndex可以更改 a 的某些名称。

例子:

In [50]: mi = pd.MultiIndex.from_product([list('AB'), list('CD'), list('EF')],
   ....:                                 names=['AB', 'CD', 'EF'])
   ....: 

In [51]: df = pd.DataFrame(list(range(len(mi))), index=mi, columns=['N'])

In [52]: df
Out[52]: 
          N
AB CD EF   
A  C  E   0
      F   1
   D  E   2
      F   3
B  C  E   4
      F   5
   D  E   6
      F   7

[8 rows x 1 columns]

In [53]: df.rename_axis(index={'CD': 'New'})
Out[53]: 
           N
AB New EF   
A  C   E   0
       F   1
   D   E   2
       F   3
B  C   E   4
       F   5
   D   E   6
       F   7

[8 rows x 1 columns]

有关更多详细信息,请参阅有关重命名的高级文档。

其他增强功能#

向后不兼容的 API 更改#

pandas 0.24.0 包含许多 API 重大更改。

增加了依赖项的最低版本#

我们更新了依赖项的最低支持版本(GH 21242GH 18742GH 23774GH 24767)。如果安装了,我们现在需要:

包裹

最低版本

必需的

麻木

1.12.0

X

瓶颈

1.2.0

快速镶木地板

0.2.1

绘图库

2.0.0

数值表达式

2.6.1

pandas-GBQ

0.8.0

皮箭头

0.9.0

pytables

3.4.2

scipy

0.18.1

xlrd

1.0.0

pytest(开发)

3.6

此外,我们不再依赖feather-format基于羽毛的存储,并将其替换为参考pyarrowGH 21639GH 23053)。

os.linesep用于line_terminator#DataFrame.to_csv

DataFrame.to_csv()现在使用os.linesep()而不是'\n' 默认的行终止符(GH 20353)。此更改仅影响在 Windows 上运行时,即使在 中传递'\r\n'时也用于行终止符。'\n'line_terminator

以前在 Windows 上的行为:

In [1]: data = pd.DataFrame({"string_with_lf": ["a\nbc"],
   ...:                      "string_with_crlf": ["a\r\nbc"]})

In [2]: # When passing file PATH to to_csv,
   ...: # line_terminator does not work, and csv is saved with '\r\n'.
   ...: # Also, this converts all '\n's in the data to '\r\n'.
   ...: data.to_csv("test.csv", index=False, line_terminator='\n')

In [3]: with open("test.csv", mode='rb') as f:
   ...:     print(f.read())
Out[3]: b'string_with_lf,string_with_crlf\r\n"a\r\nbc","a\r\r\nbc"\r\n'

In [4]: # When passing file OBJECT with newline option to
   ...: # to_csv, line_terminator works.
   ...: with open("test2.csv", mode='w', newline='\n') as f:
   ...:     data.to_csv(f, index=False, line_terminator='\n')

In [5]: with open("test2.csv", mode='rb') as f:
   ...:     print(f.read())
Out[5]: b'string_with_lf,string_with_crlf\n"a\nbc","a\r\nbc"\n'

Windows 上的新行为:

显式传递line_terminator,将 设为该字符。line terminator

In [1]: data = pd.DataFrame({"string_with_lf": ["a\nbc"],
   ...:                      "string_with_crlf": ["a\r\nbc"]})

In [2]: data.to_csv("test.csv", index=False, line_terminator='\n')

In [3]: with open("test.csv", mode='rb') as f:
   ...:     print(f.read())
Out[3]: b'string_with_lf,string_with_crlf\n"a\nbc","a\r\nbc"\n'

os.linesep在 Windows 上,的值为'\r\n',因此如果line_terminator未设置,'\r\n'则用于行终止符。

In [1]: data = pd.DataFrame({"string_with_lf": ["a\nbc"],
   ...:                      "string_with_crlf": ["a\r\nbc"]})

In [2]: data.to_csv("test.csv", index=False)

In [3]: with open("test.csv", mode='rb') as f:
   ...:     print(f.read())
Out[3]: b'string_with_lf,string_with_crlf\r\n"a\nbc","a\r\nbc"\r\n'

对于文件对象,仅newline指定行终止符是不够的。即使在这种情况下,您也必须显式传入line_terminator

In [1]: data = pd.DataFrame({"string_with_lf": ["a\nbc"],
   ...:                      "string_with_crlf": ["a\r\nbc"]})

In [2]: with open("test2.csv", mode='w', newline='\n') as f:
   ...:     data.to_csv(f, index=False)

In [3]: with open("test2.csv", mode='rb') as f:
   ...:     print(f.read())
Out[3]: b'string_with_lf,string_with_crlf\r\n"a\nbc","a\r\nbc"\r\n'

使用 Python 引擎正确处理np.nan字符串数据类型列#

Python 引擎中存在错误,其中缺失read_excel()值变成了和。 现在,这些缺失值被转换为字符串缺失指示符。 (GH 20377read_csv()'nan'dtype=strna_filter=Truenp.nan

以前的行为

In [5]: data = 'a,b,c\n1,,3\n4,5,6'
In [6]: df = pd.read_csv(StringIO(data), engine='python', dtype=str, na_filter=True)
In [7]: df.loc[0, 'b']
Out[7]:
'nan'

新行为

In [54]: data = 'a,b,c\n1,,3\n4,5,6'

In [55]: df = pd.read_csv(StringIO(data), engine='python', dtype=str, na_filter=True)

In [56]: df.loc[0, 'b']
Out[56]: nan

请注意,我们现在如何输出np.nan其本身,而不是其字符串化形式。

解析带有时区偏移的日期时间字符串#

以前,使用to_datetime() 或解析具有 UTC 偏移量的日期时间字符串DatetimeIndex会自动将日期时间转换为 UTC,而无需时区本地化。这与解析Timestamp在属性中保留 UTC 偏移量的相同日期时间字符串不一致tz。现在,当所有日期时间字符串具有相同的 UTC 偏移量(GH 17697GH 11736GH 22457)时,to_datetime()在属性中保留 UTC 偏移量tz

以前的行为

In [2]: pd.to_datetime("2015-11-18 15:30:00+05:30")
Out[2]: Timestamp('2015-11-18 10:00:00')

In [3]: pd.Timestamp("2015-11-18 15:30:00+05:30")
Out[3]: Timestamp('2015-11-18 15:30:00+0530', tz='pytz.FixedOffset(330)')

# Different UTC offsets would automatically convert the datetimes to UTC (without a UTC timezone)
In [4]: pd.to_datetime(["2015-11-18 15:30:00+05:30", "2015-11-18 16:30:00+06:30"])
Out[4]: DatetimeIndex(['2015-11-18 10:00:00', '2015-11-18 10:00:00'], dtype='datetime64[ns]', freq=None)

新行为

In [57]: pd.to_datetime("2015-11-18 15:30:00+05:30")
Out[57]: Timestamp('2015-11-18 15:30:00+0530', tz='UTC+05:30')

In [58]: pd.Timestamp("2015-11-18 15:30:00+05:30")
Out[58]: Timestamp('2015-11-18 15:30:00+0530', tz='UTC+05:30')

解析具有相同 UTC 偏移量的日期时间字符串将保留 UTC 偏移量tz

In [59]: pd.to_datetime(["2015-11-18 15:30:00+05:30"] * 2)
Out[59]: DatetimeIndex(['2015-11-18 15:30:00+05:30', '2015-11-18 15:30:00+05:30'], dtype='datetime64[ns, UTC+05:30]', freq=None)

datetime.datetime解析具有不同 UTC 偏移量的日期时间字符串现在将创建具有不同 UTC 偏移量的对象的索引

In [59]: idx = pd.to_datetime(["2015-11-18 15:30:00+05:30",
                               "2015-11-18 16:30:00+06:30"])

In[60]: idx
Out[60]: Index([2015-11-18 15:30:00+05:30, 2015-11-18 16:30:00+06:30], dtype='object')

In[61]: idx[0]
Out[61]: Timestamp('2015-11-18 15:30:00+0530', tz='UTC+05:30')

In[62]: idx[1]
Out[62]: Timestamp('2015-11-18 16:30:00+0630', tz='UTC+06:30')

传递utc=True将模仿之前的行为,但会正确指示日期已转换为 UTC

In [60]: pd.to_datetime(["2015-11-18 15:30:00+05:30",
   ....:                 "2015-11-18 16:30:00+06:30"], utc=True)
   ....: 
Out[60]: DatetimeIndex(['2015-11-18 10:00:00+00:00', '2015-11-18 10:00:00+00:00'], dtype='datetime64[ns, UTC]', freq=None)

使用#解析混合时区read_csv()

read_csv()不再默默地将混合时区列转换为 UTC ( GH 24987 )。

以前的行为

>>> import io
>>> content = """\
... a
... 2000-01-01T00:00:00+05:00
... 2000-01-01T00:00:00+06:00"""
>>> df = pd.read_csv(io.StringIO(content), parse_dates=['a'])
>>> df.a
0   1999-12-31 19:00:00
1   1999-12-31 18:00:00
Name: a, dtype: datetime64[ns]

新行为

In[64]: import io

In[65]: content = """\
   ...: a
   ...: 2000-01-01T00:00:00+05:00
   ...: 2000-01-01T00:00:00+06:00"""

In[66]: df = pd.read_csv(io.StringIO(content), parse_dates=['a'])

In[67]: df.a
Out[67]:
0   2000-01-01 00:00:00+05:00
1   2000-01-01 00:00:00+06:00
Name: a, Length: 2, dtype: object

可以看出,dtypeis 对象;列中的每个值都是一个字符串。要将字符串转换为日期时间数组,date_parser参数

In [3]: df = pd.read_csv(
   ...:     io.StringIO(content),
   ...:     parse_dates=['a'],
   ...:     date_parser=lambda col: pd.to_datetime(col, utc=True),
   ...: )

In [4]: df.a
Out[4]:
0   1999-12-31 19:00:00+00:00
1   1999-12-31 18:00:00+00:00
Name: a, dtype: datetime64[ns, UTC]

有关更多信息,请参阅解析带有时区偏移的日期时间字符串

dt.end_time#中的时间值to_timestamp(how='end')

当调用、、 、with或with ( GH 17157 )时Period, 和对象中的时间值PeriodIndex现在设置为 '23:59:59.999999999'Series.dt.end_timePeriod.end_timePeriodIndex.end_timePeriod.to_timestamp()how='end'PeriodIndex.to_timestamp()how='end'

以前的行为

In [2]: p = pd.Period('2017-01-01', 'D')
In [3]: pi = pd.PeriodIndex([p])

In [4]: pd.Series(pi).dt.end_time[0]
Out[4]: Timestamp(2017-01-01 00:00:00)

In [5]: p.end_time
Out[5]: Timestamp(2017-01-01 23:59:59.999999999)

新行为

现在,调用Series.dt.end_time将导致时间为 '23:59:59.999999999',例如 的Period.end_time情况

In [61]: p = pd.Period('2017-01-01', 'D')

In [62]: pi = pd.PeriodIndex([p])

In [63]: pd.Series(pi).dt.end_time[0]
Out[63]: Timestamp('2017-01-01 23:59:59.999999999')

In [64]: p.end_time
Out[64]: Timestamp('2017-01-01 23:59:59.999999999')

Series.unique 用于时区感知数据#

具有时区值的日期时间的返回类型Series.unique()已从对象更改numpy.ndarrayTimestamp( arrays.DatetimeArrayGH 24024 )。

In [65]: ser = pd.Series([pd.Timestamp('2000', tz='UTC'),
   ....:                  pd.Timestamp('2000', tz='UTC')])
   ....: 

以前的行为

In [3]: ser.unique()
Out[3]: array([Timestamp('2000-01-01 00:00:00+0000', tz='UTC')], dtype=object)

新行为

In [66]: ser.unique()
Out[66]: 
<DatetimeArray>
['2000-01-01 00:00:00+00:00']
Length: 1, dtype: datetime64[ns, UTC]

稀疏数据结构重构#

SparseArray、阵列支持SparseSeries和 a 中的列SparseDataFrame现在是扩展阵列(GH 21978GH 19056GH 22835)。为了符合此接口并与 pandas 的其余部分保持一致,进行了一些 API 重大更改:

  • SparseArray不再是 的子类numpy.ndarray。要将 a 转换SparseArray为 NumPy 数组,请使用numpy.asarray().

  • SparseArray.dtype和现在是, 而不是SparseSeries.dtype的实例。使用 访问底层数据类型。SparseDtypenp.dtypeSparseDtype.subtype

  • numpy.asarray(sparse_array)现在返回一个包含所有值的密集数组,而不仅仅是非填充值(GH 14167

  • SparseArray.takepandas.api.extensions.ExtensionArray.take()现在匹配( GH 19506 )的 API :

    • 的默认值allow_fill已从 更改FalseTrue

    • 现在不再接受out和参数(以前,如果指定了它们,则会引发此问题)。mode

    • indices不再允许传递标量 for 。

  • concat()稀疏和密集系列混合的结果是具有稀疏值的系列,而不是SparseSeries.

  • SparseDataFrame.combine并且DataFrame.combine_first不再支持将稀疏列与密集列组合,同时保留稀疏子类型。结果将是一个对象数据类型 SparseArray。

  • 现在允许设置SparseArray.fill_value为不同数据类型的填充值。

  • DataFrame[column]当使用稀疏值( GH 23559 )对单个列进行切片时,现在是Series具有稀疏值的 a ,而不是 a 。SparseSeries

  • Series.where()现在的结果是Series具有稀疏值的 a ,就像其他扩展数组一样(GH 24077

针对需要或可能实现大型密集阵列的操作发出一些新警告:

  • errors.PerformanceWarning当将 fillna 与 a 一起使用时,会发出A method,因为构造了一个密集数组来创建填充数组。使用 a 填充value是填充稀疏数组的有效方法。

  • errors.PerformanceWarning现在,当连接具有不同填充值的稀疏系列时,会发出A信号。继续使用第一个稀疏数组的填充值。

除了这些 API 重大更改之外,还进行了许多性能改进和错误修复

最后,Series.sparse添加了一个访问器来提供稀疏特定的方法,例如Series.sparse.from_coo().

In [67]: s = pd.Series([0, 0, 1, 1, 1], dtype='Sparse[int]')

In [68]: s.sparse.density
Out[68]: 0.6

get_dummies()总是返回一个 DataFrame #

以前,当sparse=True传递给时get_dummies(),返回值可以是 aDataFrame或 a SparseDataFrame,具体取决于是否对所有列或仅列的子集进行了虚拟编码。现在,DataFrame始终返回 a ( GH 24284 )。

以前的行为

第一个get_dummies()返回 a,DataFrame因为该列A 未进行虚拟编码。当 just传递给时,所有列都被虚拟编码,并返回 a 。["B", "C"]get_dummiesSparseDataFrame

In [2]: df = pd.DataFrame({"A": [1, 2], "B": ['a', 'b'], "C": ['a', 'a']})

In [3]: type(pd.get_dummies(df, sparse=True))
Out[3]: pandas.core.frame.DataFrame

In [4]: type(pd.get_dummies(df[['B', 'C']], sparse=True))
Out[4]: pandas.core.sparse.frame.SparseDataFrame

新行为

现在,返回类型始终是 a DataFrame

In [69]: type(pd.get_dummies(df, sparse=True))
Out[69]: pandas.core.frame.DataFrame

In [70]: type(pd.get_dummies(df[['B', 'C']], sparse=True))
Out[70]: pandas.core.frame.DataFrame

笔记

SparseDataFrame a和DataFrame具有稀疏值的a之间的内存使用情况没有差异。内存使用量将与之前版本的 pandas 相同。

在#中提高 ValueErrorDataFrame.to_dict(orient='index')

与非唯一索引一起使用时 会DataFrame.to_dict()引发错误,而不是丢失数据( GH 22801ValueErrororient='index'

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

In [72]: df
Out[72]: 
   a     b
A  1  0.50
A  2  0.75

[2 rows x 2 columns]

In [73]: df.to_dict(orient='index')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[73], line 1
----> 1 df.to_dict(orient='index')

File ~/work/pandas/pandas/pandas/util/_decorators.py:333, in deprecate_nonkeyword_arguments.<locals>.decorate.<locals>.wrapper(*args, **kwargs)
    327 if len(args) > num_allow_args:
    328     warnings.warn(
    329         msg.format(arguments=_format_argument_list(allow_args)),
    330         FutureWarning,
    331         stacklevel=find_stack_level(),
    332     )
--> 333 return func(*args, **kwargs)

File ~/work/pandas/pandas/pandas/core/frame.py:2178, in DataFrame.to_dict(self, orient, into, index)
   2075 """
   2076 Convert the DataFrame to a dictionary.
   2077 
   (...)
   2174  defaultdict(<class 'list'>, {'col1': 2, 'col2': 0.75})]
   2175 """
   2176 from pandas.core.methods.to_dict import to_dict
-> 2178 return to_dict(self, orient, into=into, index=index)

File ~/work/pandas/pandas/pandas/core/methods/to_dict.py:242, in to_dict(df, orient, into, index)
    240 elif orient == "index":
    241     if not df.index.is_unique:
--> 242         raise ValueError("DataFrame index must be unique for orient='index'.")
    243     columns = df.columns.tolist()
    244     if are_all_object_dtype_cols:

ValueError: DataFrame index must be unique for orient='index'.

勾选 DateOffset 规范化限制#

不再支持创建Tick对象 ( Day, Hour, Minute, Second, Milli, Micro, Nano) 。normalize=True这可以防止加法可能无法单调或关联的意外行为。 (GH 21427

以前的行为

In [2]: ts = pd.Timestamp('2018-06-11 18:01:14')

In [3]: ts
Out[3]: Timestamp('2018-06-11 18:01:14')

In [4]: tic = pd.offsets.Hour(n=2, normalize=True)
   ...:

In [5]: tic
Out[5]: <2 * Hours>

In [6]: ts + tic
Out[6]: Timestamp('2018-06-11 00:00:00')

In [7]: ts + tic + tic + tic == ts + (tic + tic + tic)
Out[7]: False

新行为

In [74]: ts = pd.Timestamp('2018-06-11 18:01:14')

In [75]: tic = pd.offsets.Hour(n=2)

In [76]: ts + tic + tic + tic == ts + (tic + tic + tic)
Out[76]: True

周期减法#

将 aPeriod与另一个相减Period将得到 a DateOffset。而不是整数(GH 21314

以前的行为

In [2]: june = pd.Period('June 2018')

In [3]: april = pd.Period('April 2018')

In [4]: june - april
Out [4]: 2

新行为

In [77]: june = pd.Period('June 2018')

In [78]: april = pd.Period('April 2018')

In [79]: june - april
Out[79]: <2 * MonthEnds>

Period类似地,从 a 中减goaPeriodIndex现在将返回对象Index的一个DateOffset​​,而不是一个Int64Index

以前的行为

In [2]: pi = pd.period_range('June 2018', freq='M', periods=3)

In [3]: pi - pi[0]
Out[3]: Int64Index([0, 1, 2], dtype='int64')

新行为

In [80]: pi = pd.period_range('June 2018', freq='M', periods=3)

In [81]: pi - pi[0]
Out[81]: Index([<0 * MonthEnds>, <MonthEnd>, <2 * MonthEnds>], dtype='object')

加/NaN#DataFrame

从具有 dtype 的列 NaN中添加或减go现在将引发 a而不是返回 all- 。这是为了与行为兼容( GH 22163DataFrametimedelta64[ns]TypeErrorNaTTimedeltaIndexSeries

In [82]: df = pd.DataFrame([pd.Timedelta(days=1)])

In [83]: df
Out[83]: 
       0
0 1 days

[1 rows x 1 columns]

以前的行为

In [4]: df = pd.DataFrame([pd.Timedelta(days=1)])

In [5]: df - np.nan
Out[5]:
    0
0 NaT

新行为

In [2]: df - np.nan
...
TypeError: unsupported operand type(s) for -: 'TimedeltaIndex' and 'float'

DataFrame 比较操作广播更改#

DataFrame以前,比较运算 ( ==、 、 ...)的广播行为与算术运算 ( 、 、 ...)!=的行为不一致。比较运算的行为已更改以匹配这些情况下的算术运算。 (GH 22880+-

受影响的案例有:

  • 针对具有 1 行或 1 列的二维操作现在将以与( GH 23000 )np.ndarray相同的方式进行广播。np.ndarray

  • 长度与中的行数匹配的列表或元组DataFrame现在将引发ValueError而不是逐列操作(GH 22880 .

  • 长度与 中的列数匹配的列表或元组DataFrame现在将逐行操作而不是提升ValueErrorGH 22880)。

In [84]: arr = np.arange(6).reshape(3, 2)

In [85]: df = pd.DataFrame(arr)

In [86]: df
Out[86]: 
   0  1
0  0  1
1  2  3
2  4  5

[3 rows x 2 columns]

以前的行为

In [5]: df == arr[[0], :]
    ...: # comparison previously broadcast where arithmetic would raise
Out[5]:
       0      1
0   True   True
1  False  False
2  False  False
In [6]: df + arr[[0], :]
...
ValueError: Unable to coerce to DataFrame, shape must be (3, 2): given (1, 2)

In [7]: df == (1, 2)
    ...: # length matches number of columns;
    ...: # comparison previously raised where arithmetic would broadcast
...
ValueError: Invalid broadcasting comparison [(1, 2)] with block values
In [8]: df + (1, 2)
Out[8]:
   0  1
0  1  3
1  3  5
2  5  7

In [9]: df == (1, 2, 3)
    ...:  # length matches number of rows
    ...:  # comparison previously broadcast where arithmetic would raise
Out[9]:
       0      1
0  False   True
1   True  False
2  False  False
In [10]: df + (1, 2, 3)
...
ValueError: Unable to coerce to Series, length must be 2: given 3

新行为

# Comparison operations and arithmetic operations both broadcast.
In [87]: df == arr[[0], :]
Out[87]: 
       0      1
0   True   True
1  False  False
2  False  False

[3 rows x 2 columns]

In [88]: df + arr[[0], :]
Out[88]: 
   0  1
0  0  2
1  2  4
2  4  6

[3 rows x 2 columns]
# Comparison operations and arithmetic operations both broadcast.
In [89]: df == (1, 2)
Out[89]: 
       0      1
0  False  False
1  False  False
2  False  False

[3 rows x 2 columns]

In [90]: df + (1, 2)
Out[90]: 
   0  1
0  1  3
1  3  5
2  5  7

[3 rows x 2 columns]
# Comparison operations and arithmetic operations both raise ValueError.
In [6]: df == (1, 2, 3)
...
ValueError: Unable to coerce to Series, length must be 2: given 3

In [7]: df + (1, 2, 3)
...
ValueError: Unable to coerce to Series, length must be 2: given 3

DataFrame算术运算广播变化#

DataFrame处理二维 np.ndarray对象时的算术运算现在以与广播相同的方式进行广播np.ndarray 。 (GH 23000

In [91]: arr = np.arange(6).reshape(3, 2)

In [92]: df = pd.DataFrame(arr)

In [93]: df
Out[93]: 
   0  1
0  0  1
1  2  3
2  4  5

[3 rows x 2 columns]

以前的行为

In [5]: df + arr[[0], :]   # 1 row, 2 columns
...
ValueError: Unable to coerce to DataFrame, shape must be (3, 2): given (1, 2)
In [6]: df + arr[:, [1]]   # 1 column, 3 rows
...
ValueError: Unable to coerce to DataFrame, shape must be (3, 2): given (3, 1)

新行为

In [94]: df + arr[[0], :]   # 1 row, 2 columns
Out[94]: 
   0  1
0  0  2
1  2  4
2  4  6

[3 rows x 2 columns]

In [95]: df + arr[:, [1]]   # 1 column, 3 rows
Out[95]: 
   0   1
0  1   2
1  5   6
2  9  10

[3 rows x 2 columns]

系列和索引数据类型不兼容#

SeriesIndex现在,当数据与传递的数据不兼容时,构造函数会引发(dtype=GH 15832

以前的行为

In [4]: pd.Series([-1], dtype="uint64")
Out [4]:
0    18446744073709551615
dtype: uint64

新行为

In [4]: pd.Series([-1], dtype="uint64")
Out [4]:
...
OverflowError: Trying to coerce negative values to unsigned integers

连接变化#

现在,调用具有 NA 值的pandas.concat()整数会导致它们在与除另一个整数Categorical之外的任何内容连接时被作为对象处理( GH 19214Categorical

In [96]: s = pd.Series([0, 1, np.nan])

In [97]: c = pd.Series([0, 1, np.nan], dtype="category")

以前的行为

In [3]: pd.concat([s, c])
Out[3]:
0    0.0
1    1.0
2    NaN
0    0.0
1    1.0
2    NaN
dtype: float64

新行为

In [98]: pd.concat([s, c])
Out[98]: 
0    0.0
1    1.0
2    NaN
0    0.0
1    1.0
2    NaN
Length: 6, dtype: float64

Datetimelike API 更改#

其他 API 更改#

  • 一个新构造的DataFrame带有整数的空dtype现在只会被转换为float64如果index指定(GH 22858

  • Series.str.cat()现在将引发 ifothersset( GH 23009 )

  • 将标量值传递给DatetimeIndexorTimedeltaIndex现在将提高TypeError而不是ValueErrorGH 23539

  • max_rows由于截断由(GH 23818)处理,因此max_cols参数被删除HTMLFormatterDataFrameFormatter

  • read_csv()ValueError如果将缺少值的列声明为具有 dtype bool( GH 20591 ),现在将引发

  • DataFrame现在MultiIndex.to_frame()保证结果的列顺序与MultiIndex.names顺序匹配。 (GH 22420

  • 错误地传递 aDatetimeIndexMultiIndex.from_tuples(),而不是元组序列,现在引发 aTypeError而不是 a ValueError( GH 24024 )

  • pd.offsets.generate_range()参数time_rule已被删除;使用offsetGH 24157

  • 在 0.23.x 中,pandas 会ValueError在数字列(例如intdtyped 列)和objectdtyped 列(GH 9780)合并时引发 a 。我们重新启用了合并object和其他数据类型的功能; pandas 仍然会在数字和object仅由字符串组成的 dtyped 列之间合并时引发(GH 21681

  • MultiIndex访问具有重复名称 的 a 级别(例如在 中get_level_values())现在会引发 aValueError而不是 a KeyError( GH 21678 )。

  • 如果子类型无效,则无效的构造IntervalDtype现在将始终引发 aTypeError而不是 a ( GH 21185 )ValueError

  • 尝试使用DataFrame非唯一的重新索引 aMultiIndex现在会引发 aValueError而不是 an Exception( GH 21770 )

  • Index减法将尝试按元素进行操作而不是提升TypeErrorGH 19369

  • pandas.io.formats.style.Stylernumber-format使用时支持属性to_excel()GH 22015

  • DataFrame.corr()现在,当提供无效方法时,Series.corr()会引发ValueError和有用的错误消息(而不是 GH 22298KeyError

  • shift()现在将始终返回一个副本,而不是以前在移位 0 时返回 self 的行为 ( GH 22397 )

  • DataFrame.set_index()现在提供更好(且频率更低)的 KeyError,ValueError针对不正确的类型引发 a,并且不会因重复的列名而失败drop=True。 (GH 22484

  • 现在,使用相同类型的多个 ExtensionArray 对 DataFrame 的单行进行切片可以保留 dtype,而不是强制转换为对象 ( GH 22784 )

  • DateOffset属性_cacheable和方法_should_cache已被删除(GH 23118

  • Series.searchsorted(),当提供要搜索的标量值时,现在返回标量而不是数组 ( GH 23801 )。

  • Categorical.searchsorted(),当提供要搜索的标量值时,现在返回标量而不是数组(GH 23466)。

  • Categorical.searchsorted()如果在其类别中找不到搜索的键(GH 23466),现在会引发 aKeyError而不是 a 。ValueError

  • Index.hasnans()现在Series.hasnans()总是返回一个 python 布尔值。以前,可以根据情况返回 python 或 numpy 布尔值 ( GH 23294 )。

  • DataFrame.to_html()和的参数顺序DataFrame.to_string()被重新排列以彼此一致。 (GH 23614

  • CategoricalIndex.reindex()ValueError如果目标索引不唯一并且不等于当前索引,现在会引发 a 。以前,仅当目标索引不是分类数据类型 ( GH 23963 ) 时才会引发该问题。

  • Series.to_list()Index.to_list()现在Series.tolist分别是Index.tolist( GH 8826 )的别名

  • SparseSeries.unstack现在的结果是DataFrame具有稀疏值的 a,而不是 a SparseDataFrame( GH 24372 )。

  • DatetimeIndex并且TimedeltaIndex不再忽略 dtype 精度。传递非纳秒分辨率的 dtype 将引发ValueError( GH 24753 )

扩展类型更改#

平等性和可哈希性

pandas 现在要求扩展数据类型是可散列的(即各自的 ExtensionDtype对象;可散列性不是相应值的要求ExtensionArray)。基类实现默认的__eq____hash__.如果您有参数化数据类型,则应该更新ExtensionDtype._metadata元组以匹配您的方法的签名 __init__。请参阅pandas.api.extensions.ExtensionDtype更多信息(GH 22476)。

新的和改变的方法

数据类型更改

  • ExtensionDtype已经获得了从字符串数据类型实例化的能力,例如decimal实例化一个已注册的DecimalDtype;此外还ExtensionDtype获得了方法construct_array_typeGH 21185

  • 添加ExtensionDtype._is_numeric用于控制扩展数据类型是否被视为数字(GH 22290)。

  • 添加pandas.api.types.register_extension_dtype()以向 pandas 注册扩展类型(GH 22664

  • 将、和的属性更新.type为dtype 的实例(分别为、和)( GH 22938 )PeriodDtypeDatetimeTZDtypeIntervalDtypePeriodTimestampInterval

运营商支持

Series基于 a现在ExtensionArray支持算术和比较运算符(GH 19577)。有两种方法可以为操作员提供支持ExtensionArray

  1. 定义子类中的每个运算符ExtensionArray

  2. 使用 pandas 的运算符实现,该实现依赖于已在ExtensionArray.

有关添加运算符支持的两种方法的详细信息,请参阅ExtensionArray 运算符支持文档部分。

其他变化

Bug修复

弃用#

不推荐使用日期时间和时间增量进行整数加/减#

过go,在某些情况下,用户可以从 、 和 中添加或减go整数或整数数据Timestamp类型DatetimeIndex数组TimedeltaIndex

此用法现已弃用。而是添加或减go对象freq属性的整数倍(GH 21939GH 23878)。

以前的行为

In [5]: ts = pd.Timestamp('1994-05-06 12:15:16', freq=pd.offsets.Hour())
In [6]: ts + 2
Out[6]: Timestamp('1994-05-06 14:15:16', freq='H')

In [7]: tdi = pd.timedelta_range('1D', periods=2)
In [8]: tdi - np.array([2, 1])
Out[8]: TimedeltaIndex(['-1 days', '1 days'], dtype='timedelta64[ns]', freq=None)

In [9]: dti = pd.date_range('2001-01-01', periods=2, freq='7D')
In [10]: dti + pd.Index([1, 2])
Out[10]: DatetimeIndex(['2001-01-08', '2001-01-22'], dtype='datetime64[ns]', freq=None)

新行为

In [108]: ts = pd.Timestamp('1994-05-06 12:15:16', freq=pd.offsets.Hour())

In[109]: ts + 2 * ts.freq
Out[109]: Timestamp('1994-05-06 14:15:16', freq='H')

In [110]: tdi = pd.timedelta_range('1D', periods=2)

In [111]: tdi - np.array([2 * tdi.freq, 1 * tdi.freq])
Out[111]: TimedeltaIndex(['-1 days', '1 days'], dtype='timedelta64[ns]', freq=None)

In [112]: dti = pd.date_range('2001-01-01', periods=2, freq='7D')

In [113]: dti + pd.Index([1 * dti.freq, 2 * dti.freq])
Out[113]: DatetimeIndex(['2001-01-08', '2001-01-22'], dtype='datetime64[ns]', freq=None)

将整数数据和时区传递给 DatetimeIndex #

DatetimeIndex在 pandas 的未来版本中,传递整数数据和时区的行为正在发生变化。以前,这些被解释为所需时区的墙上时间。将来,这些将被解释为 UTC 的墙上时间,然后转换为所需的时区 ( GH 24559 )。

默认行为保持不变,但发出警告:

In [3]: pd.DatetimeIndex([946684800000000000], tz="US/Central")
/bin/ipython:1: FutureWarning:
    Passing integer-dtype data and a timezone to DatetimeIndex. Integer values
    will be interpreted differently in a future version of pandas. Previously,
    these were viewed as datetime64[ns] values representing the wall time
    *in the specified timezone*. In the future, these will be viewed as
    datetime64[ns] values representing the wall time *in UTC*. This is similar
    to a nanosecond-precision UNIX epoch. To accept the future behavior, use

        pd.to_datetime(integer_data, utc=True).tz_convert(tz)

    To keep the previous behavior, use

        pd.to_datetime(integer_data).tz_localize(tz)

 #!/bin/python3
 Out[3]: DatetimeIndex(['2000-01-01 00:00:00-06:00'], dtype='datetime64[ns, US/Central]', freq=None)

正如警告消息所解释的,通过指定整数值是 UTC,然后转换为最终时区来选择未来的行为:

In [99]: pd.to_datetime([946684800000000000], utc=True).tz_convert('US/Central')
Out[99]: DatetimeIndex(['1999-12-31 18:00:00-06:00'], dtype='datetime64[ns, US/Central]', freq=None)

可以通过直接本地化到最终时区来保留旧行为:

In [100]: pd.to_datetime([946684800000000000]).tz_localize('US/Central')
Out[100]: DatetimeIndex(['2000-01-01 00:00:00-06:00'], dtype='datetime64[ns, US/Central]', freq=None)

将时区感知系列和索引转换为 NumPy 数组#

Series默认情况下,从时区感知的日期时间数据或使用时区感知的日期时间数据进行的转换Index将更改为保留时区(GH 23569)。

NumPy 没有用于时区感知日期时间的专用数据类型。在过go,使用时区感知数据时间转换SeriesDatetimeIndex会通过以下方式转换为 NumPy 数组:

  1. 将 tz 感知数据转换为 UTC

  2. 删除时区信息

  3. 返回numpy.ndarray带有datetime64[ns]dtype 的a

pandas 的未来版本将通过返回对象数据类型 NumPy 数组来保留时区信息,其中每个值都是Timestamp附加了正确时区的a

In [101]: ser = pd.Series(pd.date_range('2000', periods=2, tz="CET"))

In [102]: ser
Out[102]: 
0   2000-01-01 00:00:00+01:00
1   2000-01-02 00:00:00+01:00
Length: 2, dtype: datetime64[ns, CET]

默认行为保持不变,但会发出警告

In [8]: np.asarray(ser)
/bin/ipython:1: FutureWarning: Converting timezone-aware DatetimeArray to timezone-naive
      ndarray with 'datetime64[ns]' dtype. In the future, this will return an ndarray
      with 'object' dtype where each element is a 'pandas.Timestamp' with the correct 'tz'.

        To accept the future behavior, pass 'dtype=object'.
        To keep the old behavior, pass 'dtype="datetime64[ns]"'.
  #!/bin/python3
Out[8]:
array(['1999-12-31T23:00:00.000000000', '2000-01-01T23:00:00.000000000'],
      dtype='datetime64[ns]')

通过指定dtype

以前的行为

In [103]: np.asarray(ser, dtype='datetime64[ns]')
Out[103]: 
array(['1999-12-31T23:00:00.000000000', '2000-01-01T23:00:00.000000000'],
      dtype='datetime64[ns]')

未来的行为

# New behavior
In [104]: np.asarray(ser, dtype=object)
Out[104]: 
array([Timestamp('2000-01-01 00:00:00+0100', tz='CET'),
       Timestamp('2000-01-02 00:00:00+0100', tz='CET')], dtype=object)

或者通过使用Series.to_numpy()

In [105]: ser.to_numpy()
Out[105]: 
array([Timestamp('2000-01-01 00:00:00+0100', tz='CET'),
       Timestamp('2000-01-02 00:00:00+0100', tz='CET')], dtype=object)

In [106]: ser.to_numpy(dtype="datetime64[ns]")
Out[106]: 
array(['1999-12-31T23:00:00.000000000', '2000-01-01T23:00:00.000000000'],
      dtype='datetime64[ns]')

上述所有内容DatetimeIndex也适用于具有 tz 感知值的 a。

删除先前版本的弃用/更改#

性能改进#

Bug修复

分类#

  • 错误在于Categorical.from_codes()其中NaN的值codes被默默地转换为0GH 21767)。将来这将引发ValueError.还改变了 的行为。.from_codes([1.1, 2.0])

  • 无论值如何,值始终位于前面Categorical.sort_values()的错误。 (GH 22556)。NaNna_position

  • 使用布尔值索引时出现错误Categorical。现在布尔值Categorical被视为布尔掩码(GH 22665

  • 在更改 dtype 强制转换后,CategoricalIndex使用空值和布尔类别构造a 会引发 a ( GH 22702 )。ValueError

  • Categorical.take()用户提供的fill_value未对 进行编码的错误fill_value,这可能会导致ValueError、不正确的结果或分段错误 ( GH 23296 )。

  • 在 中Series.unstack(),指定fill_value类别中不存在的 a 现在会引发 aTypeError而不是忽略fill_value( GH 23284 )

  • 对分类数据进行重新采样和聚合时出现错误DataFrame.resample(),分类数据类型丢失。 (GH 23227

  • -accessor的许多方法中存在错误.str,调用构造函数时总是失败CategoricalIndex.strGH 23555GH 23556

  • Series.where()丢失分类数据的分类数据类型的错误( GH 24077 )

  • Categorical.apply()值可能被不可预测地处理的错误NaN。它们现在保持不变(GH 24241

  • 针对( GH 24630 )进行操作时,Categorical比较方法中的错误会错误地引发ValueErrorDataFrame

  • Categorical.set_categories()设置较少的新类别导致rename=True分段错误的错误( GH 24675

类似日期时间#

时间增量#

时区

偏移量#

  • FY5253日期偏移量可能错误地引发AssertionError算术运算中的错误( GH 14774

  • DateOffset关键字参数week和被接受和忽略的错误milliseconds。通过这些现在将提高ValueErrorGH 19398

  • DateOffset添加DataFramePeriodIndex错误提高时的错误TypeErrorGH 23215

  • DateOffset将对象与非 DateOffset 对象(特别是字符串)进行比较时的错误,引发ValueError而不是返回False相等检查和True不相等检查(GH 23524

数字#

转换

字符串#

间隔

  • 构造函数中的错误IntervalIndex,其中closed参数并不总是覆盖推断的closedGH 19370

  • repr中的错误IntervalIndex,其中间隔列表后缺少尾随逗号 ( GH 20611 )

  • Interval标量算术运算未保留值的错误closedGH 22313

  • IntervalIndex使用类似日期时间的值进行索引时引发的错误KeyErrorGH 20636

  • IntervalTree数据包含NaN触发警告并导致索引查询不正确的错误IntervalIndexGH 23352

索引#

  • DataFrame.ne()如果列包含列名称“dtype”,则错误会失败( GH 22383

  • KeyError询问单个缺失标签时的回溯.loc现在更短、更清晰(GH 21557

  • PeriodIndexKeyError现在,当查找格式错误的字符串时,会发出 a ,这与DatetimeIndex( GH 22803 )的行为一致

  • .ix被要求在MultiIndex具有第一级整数类型的 a 中缺少整数标签时,它现在会引发 a KeyError,与 flat 的情况一致Int64Index,而不是回退到位置索引(GH 21593

  • Index.reindex()重新索引 tz-naive 和 tz-aware 时出现错误DatetimeIndexGH 8306

  • Series.reindex()使用 dtype 重新索引空系列时出现错误(GH 20869datetime64[ns, tz]

  • 使用时区感知DataFrame设置值时出现错误(GH 11365.locDatetimeIndex

  • DataFrame.__getitem__现在接受字典和字典键作为标签的列表,与Series.__getitem__GH 21294)一致

  • DataFrame[np.nan]当列不唯一时修复( GH 21428

  • DatetimeIndex使用纳秒分辨率日期和时区建立索引时出现错误( GH 11679

  • 使用包含负值的 Numpy 数组进行索引会改变索引器的错误(GH 21867

  • 混合索引不允许整数的错误.atGH 19860

  • Float64Index.get_locKeyError现在当布尔键通过时引发。 (GH 19087

  • DataFrame.loc()使用IntervalIndex( GH 19977 )进行索引时出现错误

  • Index不再损坏NoneNaNNaT,即它们被视为三个不同的键。然而,对于数字索引,所有三个仍然被强制为NaNGH 22332

  • 如果标量是浮点型而其是整数数据类型时的错误( GH 22085scalar in IndexIndex

  • MultiIndex.set_levels()当级别值不可下标时出现错误( GH 23273

  • 设置 timedelta 列Index会导致其转换为双倍,从而失go精度的错误(GH 23511

  • Index.union()在某些情况下,结果Index.intersection()名称Index未正确计算的错误( GH 9943GH 9862

  • Index使用布尔值进行切片时Index可能会出现错误TypeErrorGH 22533

  • PeriodArray.__setitem__接受切片和类似列表的值时出现错误( GH 23978

  • 错误DatetimeIndexTimedeltaIndex其中索引Ellipsis将丢失其freq属性(GH 21282

  • iat使用它分配不兼容的值会创建新列的错误( GH 23236

丢失的

  • 当一列包含 dtype 时DataFrame.fillna()a会引发错误(GH 15522ValueErrordatetime64[ns, tz]

  • Series.hasnans()如果在初始调用后引入空元素,则可能会错误地缓存并返回错误的答案(GH 19700

  • Series.isin()现在对于 -dtype 也将所有 NaN 浮点数视为相等np.object_。此行为与 float64 ( GH 22119 )的行为一致

  • unique()不再破坏 NaN 浮点和-dtypeNaT的 -object np.object_,即NaT不再强制为 NaN 值并被视为不同的实体。 (GH 22295

  • DataFrame现在Series可以使用硬化掩码正确处理 numpy 掩码数组。以前,使用硬掩码从掩码数组构造 DataFrame 或 Series 会创建一个包含基础值的 pandas 对象,而不是预期的 NaN。 (GH 24574

  • DataFrame构造函数中的错误,dtype在处理 numpy 屏蔽记录数组时不遵守参数。 (GH 24874

多重索引#

IO #

绘图#

GroupBy/重新采样/滚动#

  • Rolling.min()Rolling.max()with中的错误closed='left',类似日期时间的索引,并且该系列中只有一个条目导致段错误(GH 24718

  • 错误GroupBy.first()导致时区信息GroupBy.last()丢失as_index=FalseGH 15884

  • DateFrame.resample()跨越 DST 边界进行下采样时出现错误( GH 8531 )

  • 当 n > 1 时,日期锚定中存在DateFrame.resample()偏移量错误( GH 24127Day

  • 当分组变量仅包含 NaN 且 numpy 版本 < 1.13 ( GH 21956 )时ValueError,调用SeriesGroupBy.count()a 的方法 时会错误地引发错误。SeriesGroupBy

  • Rolling.min()with和类似日期时间的索引中的多个错误closed='left'会导致错误的结果和段错误。 (GH 21704

  • Resampler.apply()将位置参数传递给应用函数时出现错误( GH 14615)。

  • 传递给kwargSeries.resample()时出现错误(GH 7687)。numpy.timedelta64loffset

  • Resampler.asfreq()当 的频率TimedeltaIndex是新频率的子周期时出现错误( GH 13022 )。

  • SeriesGroupBy.mean()当值是整数但无法放入 int64 内部时出现错误,而是溢出。 (GH 22487

  • RollingGroupby.agg()现在ExpandingGroupby.agg()支持多个聚合函数作为参数(GH 15072

  • 在 DST 过渡期间按每周偏移量 () 重新采样时DataFrame.resample()出现错误( GH 9119GH 21459Series.resample()'W'

  • 聚合期间未遵守参数的DataFrame.expanding()错误( GH 23372 )axis

  • GroupBy.transform()当输入函数可以接受 a 但重命名它时导致缺失值的错误DataFrame( GH 23455 )。

  • GroupBy.nth()不总是保留列顺序的错误( GH 20760

  • GroupBy.rank()当一个小组只有一名成员时会出现method='dense'错误(GH 23666)。pct=TrueZeroDivisionError

  • GroupBy.rank()与空组通话并pct=True提出ZeroDivisionError( GH 22519 )

  • 重新采样DataFrame.resample()时出现错误(GH 13223)。NaTTimeDeltaIndex

  • DataFrame.groupby()选择列时不尊重observed参数,而是始终使用错误observed=FalseGH 23970

  • 在计算百分比变化时,以前会出现错误SeriesGroupBy.pct_change()或会跨组工作,现在它可以正确地按组工作( GH 21200GH 21235)。DataFrameGroupBy.pct_change()

  • 阻止创建具有大量 (2^32) 行的哈希表的错误 ( GH 22805 )

  • 根据分类原因进行分组时,groupby 中存在错误,如果分类列中存在和 ,则ValueError分组不正确( GH 24740GH 21151)。observed=Truenan

重塑#

稀疏#

  • 现在可以将布尔值、日期时间或 timedelta 列更新为稀疏(GH 22367

  • Series.to_sparse()系列已经持有稀疏数据但无法正确构建的错误( GH 22389

  • 向 SparseArray 构造函数提供 a不再为所有 dtypessparse_index默认 na 值。现在使用np.nan正确的 na_value 。data.dtype

  • SparseArray.nbytes由于不包含稀疏索引的大小而低估了其内存使用情况的错误。

  • Series.shift()改进了非 NA的性能fill_value,因为值不再转换为密集数组。

  • 按稀疏列分组时DataFrame.groupby不包含fill_value在非 NA 组中的错误( GH 5078 )fill_value

  • 具有布尔值的一元反转运算符 ( ~)中的错误SparseSeries。其性能也得到了改进(GH 22835

  • SparseArary.unique()不返回唯一值的错误( GH 19595

  • 错误SparseArray.nonzero()SparseDataFrame.dropna()返回偏移/不正确的结果(GH 21172

  • 数据类型会失go稀疏性的错误DataFrame.apply()GH 23744

  • 连接具有全稀疏值concat()的列表并更改并转换为密集系列时出现错误( GH 24371Seriesfill_value

风格

  • background_gradient()现在采用一个text_color_threshold参数来根据背景颜色的亮度自动使文本颜色变亮。这提高了深色背景颜色的可读性,而无需限制背景颜色图范围。 (GH 21258

  • background_gradient()现在还支持表式应用程序(除了行式和列式之外)axis=NoneGH 15204

  • bar()现在还支持表式应用程序(除了行式和列式之外)并使用和axis=None设置剪切范围(GH 21548GH 21526)。价值观也得到妥善处理。vminvmaxNaN

构建更改#

其他

  • 如果在 pandas 之前导入某些其他 C 库,使用外部链接声明 C 变量会导致导入错误。 (GH 24113

贡献者#

共有 337 人为此版本贡献了补丁。名字带有“+”的人首次贡献了补丁。

  • AJ 戴卡 +

  • AJ 普赖尔博士 +

  • 亚伦·克里奇利

  • 亚当·胡珀

  • 亚当·斯图尔特

  • 亚当·金

  • 亚当·克里蒙 +

  • 艾迪生·林奇 +

  • 艾伦·霍格 +

  • 亚历克斯·拉杜 +

  • 亚历克斯·瑞奇克

  • 亚历克斯·斯特里克·范·林斯霍滕 +

  • 亚历克斯·沃尔科夫 +

  • 亚历山大·布赫科夫斯基

  • 亚历山大·赫斯 +

  • 亚历山大·波诺马罗夫 +

  • 艾莉森·布朗+

  • 阿里·西夫吉

  • 安德鲁

  • 安德鲁·格罗斯 +

  • 安德鲁·斯波特 +

  • 安迪+

  • 阿尼凯特·乌塔姆 +

  • 安贾利2019 +

  • 安佳娜S+

  • 安蒂·凯霍拉 +

  • 阿努迪普·图巴蒂 +

  • 阿琼·夏尔马 +

  • 阿明·瓦尔绍卡

  • 阿尔乔姆·博加乔夫

  • 阿廷·萨拉夫 +

  • 巴里·菲茨杰拉德 +

  • 巴特·阿尔特曼 +

  • 本·詹姆斯 +

  • 本·尼尔森 +

  • 本杰明·格罗夫 +

  • 本杰明·罗威尔 +

  • 伯努瓦·帕奎特 +

  • 刘鲍里斯 +

  • 布雷特·瑙尔

  • 布莱恩·崔 +

  • CAM 格拉赫 +

  • 卡尔·约翰 +

  • 查默·洛

  • 常社

  • 查尔斯·大卫+

  • 卓廷浩

  • 克里斯

  • 克里斯·罗伯茨 +

  • 克里斯托弗·惠兰

  • 楚青浩 +

  • Da Cheezy Mobsta +

  • 达米尼·萨提亚

  • 丹尼尔·希梅尔斯坦

  • 丹尼尔·萨克斯顿 +

  • 达西·迈耶 +

  • 数据监察员

  • 大卫·阿科斯

  • 大卫·克里奇

  • 院长朗萨姆 +

  • 迭戈·阿尔格塔 +

  • 迭戈·托雷斯 +

  • 多巴蒂莫 +

  • 道格·拉托内尔 +

  • 欧文博士

  • 迪伦·德米特里·格雷 +

  • 埃里克·博克瑟 +

  • 埃里克·谢

  • 埃里克+

  • 埃里克·尼尔森 +

  • 法比安·哈斯 +

  • 法比安·雷特科斯基

  • 法比安·奥莱尔 +

  • 法卡比尔·阿明 +

  • 菲潘 +

  • 费尔南多·马盖拉特 +

  • 弗洛里安·穆勒 +

  • 法比奥·罗萨多 +

  • 加布·费尔南多

  • 加布里埃尔·里德 +

  • 吉夫林·拉贾雅

  • 乔亚·巴林 +

  • 盖尔特

  • 柴原刚介 +

  • 格雷厄姆·英格斯

  • 纪尧姆·盖伊

  • 纪尧姆·勒梅特 +

  • 汉娜·费奇兰

  • 吴浩辰

  • 休伯特+

  • 休伯特Kl +

  • 炫真相 +

  • 伊恩·巴尔

  • 伊格纳西奥·维加拉·考塞尔 +

  • 欧文·勒斯蒂格 +

  • 伊斯文C+

  • 雅各布·罗塔

  • 雅各布·贾马尔 +

  • 詹姆斯·布尔博 +

  • 詹姆斯·迈亚特 +

  • 詹姆斯·怀恩加 +

  • 简·鲁道夫

  • 贾里德·格罗夫斯 +

  • 贾森·凯利 +

  • 贾瓦德·努尔巴赫什 +

  • 杰·奥弗达尔 +

  • 杰夫·雷巴克

  • 于正珉 +

  • 杰里米·申德尔

  • 杰罗德·埃斯塔帕 +

  • 杰斯珀·德拉姆施 +

  • 吉姆·全 +

  • 乔·杰夫尼克

  • 乔尔·诺斯曼

  • 乔尔·奥斯特布洛姆 +

  • 乔迪·竞赛

  • 豪尔赫·洛佩斯·富约 +

  • 乔里斯·范登博什

  • 何塞·奎诺内斯 +

  • 何塞·里维拉-卢比奥 +

  • 乔什

  • 君+

  • 郑宇森 +

  • 董凯琪+

  • 卡扬·戈卡莱

  • 姜有三+

  • 卡尔·邓克尔·沃纳 +

  • 卡马尼亚·阿加瓦尔 +

  • 凯文·马卡姆 +

  • 凯文·谢泼德

  • 李基米+

  • 库斯塔夫·萨马达尔 +

  • 克里希纳+

  • 克里斯蒂安·霍尔斯海默 +

  • 克谢尼娅·盖莱蒂娜 +

  • 凯尔·普雷斯特 +

  • 力杰+

  • 内存泄漏 +

  • 李进+

  • 竹内光

  • 卢卡·多尼尼 +

  • 卢西亚诺·维奥拉 +

  • 麦诗珍 +

  • 马克·加西亚

  • 马吕斯·波特吉特 +

  • 马克·西科拉 +

  • 马库斯·迈耶 +

  • 马琳·席尔瓦·马切纳 +

  • 马丁·巴布卡 +

  • 马坦科赫 +

  • 马特乌斯·沃什 +

  • 马修·托珀 +

  • 马特·博格斯+

  • 马特·库珀 +

  • 马特·威廉姆斯 +

  • 马修·吉尔伯特

  • 马修·罗斯克

  • 马克斯·坎特

  • 迈克尔·奥金佐夫

  • 迈克尔·西尔弗斯坦 +

  • 迈克尔-J-沃德 +

  • 米凯尔·勋根 +

  • 米格尔·桑切斯·德莱昂·佩克 +

  • 李明

  • 米塔尔

  • 米奇·内格斯

  • 邵孟生 +

  • 金文洙 +

  • 莫尔塔达·梅哈尔

  • 迈尔斯·布雷斯韦特

  • 尼尔·贾恩 +

  • 尼古拉斯·墨索里诺 +

  • 尼古拉斯·迪克路特 +

  • 尼基尔·库马尔·蒙加尼 +

  • 尼古拉塔·格林纳齐 +

  • 翁德雷·科克斯

  • 巴勃罗·安布罗休+

  • 吴佩梅 +

  • 冻糕G+

  • 帕特里克公园 +

  • 保罗

  • 保罗·甘塞尔

  • 保罗·雷迪

  • 保罗·范·马尔布雷特 +

  • 菲利普·克劳德

  • 彼得罗·巴蒂斯顿

  • 皮尤什·阿加瓦尔 +

  • 普拉巴卡兰·库马雷尚 +

  • 普尔基特·马卢

  • 皮里·科瓦宁

  • 拉吉布·米特拉 +

  • 雷东内特·路易斯 +

  • 里斯·帕里 +

  • 瑞克+

  • 罗宾

  • 罗伊.r +

  • 罗曼萨+

  • 罗曼·伊曼库洛夫 +

  • 罗曼·尤尔恰克 +

  • 李瑞晶 +

  • 瑞安+

  • 瑞安·拿撒勒 +

  • 吕迪格·布施 +

  • 申承勋 +

  • 桑德琳·帕托 +

  • 尹相雄

  • 桑托什·库马尔 +

  • 索拉夫·查克拉沃蒂 +

  • 斯科特·麦卡利斯特 +

  • 陈肖恩 +

  • 沙迪·阿基基 +

  • 唐胜普+

  • 希里什·卡达姆 +

  • 西蒙·霍金斯 +

  • 西蒙·里德尔 +

  • 西蒙·巴索

  • 辛赫克斯

  • Soyoun(Rose) Kim +

  • 斯里尼瓦斯·雷迪·塔蒂帕西 (శ్రీనివాస్ రెడ్డి తాటిపర్తి) +

  • 史蒂芬·利彭斯 +

  • 斯特凡诺·钱丘利

  • 斯特凡诺·米科利 +

  • 史蒂芬·柴尔兹

  • 史蒂芬·帕斯科

  • 史蒂夫·贝克 +

  • 史蒂夫·库克 +

  • 史蒂夫·道尔 +

  • 史蒂芬·塔尔加德 +

  • 边苏民 +

  • 索伦+

  • 塔马斯·纳吉 +

  • 坦尼娅·贾恩 +

  • 深泽塔尔博

  • 登乌+

  • 蒂亚戈·科代罗·达·丰塞卡 +

  • 蒂埃里·莫伊桑

  • 蒂维扬·塔纳帕拉辛加姆 +

  • 托马斯·伦塔利 +

  • 蒂姆·D·史密斯 +

  • 蒂姆·斯瓦斯特

  • 汤姆·奥格斯普格

  • 托马斯·克鲁茨科夫斯基 +

  • 陶托尼+

  • 三重0+

  • 特罗尔斯·尼尔森 +

  • 图欣·马哈茂德 +

  • 泰勒·雷迪 +

  • 乌德夏·辛格

  • 乌韦·科恩 +

  • 瓦迪姆·巴尔达 +

  • 瓦拉德·冈贾尔 +

  • 维克多·马里亚马 +

  • 维克多别墅

  • 文森特·拉

  • 维多利亚·海伦娜 +

  • 武乐

  • 维姆·贾恩 +

  • 顾伟文 +

  • 文焕

  • 韦斯·特纳

  • 威尔·谭+

  • 威廉·艾德

  • 金汝珍 +

  • 伊扎克·安德拉德 +

  • 吴越成 +

  • 尤利娅·多夫任科 +

  • 尤里·贝达 +

  • 扎克·哈特菲尔德-多兹 +

  • 阿伯雷斯+

  • 艾尔塔纳维 +

  • 艾乔+

  • 阿里姆大师1

  • αCTzo7G+

  • 安菲+

  • 阿拉阿拉在线+

  • 天蓝色管道[bot] +

  • 贝纳瑟91 +

  • bk521234 +

  • cgangwar11 +

  • 克里斯-B1

  • CXL923CC +

  • 达尔贝克+

  • 丹尼贤金 +

  • 黑暗精灵+

  • 大卫刘布拉特尔1

  • 大卫·瓦伦特 +

  • 放气SOCO

  • doosik_bae +

  • 迪兰切斯 +

  • 爱德华多·瑙费尔·斯凯蒂诺 +

  • 欧元10+

  • 伊万杰琳内利乌 +

  • 风一气+

  • 菲迪奥德

  • FL4P +

  • 弗莱姆格鲁伯 +

  • 格菲扬

  • H-维蒂纳里

  • 哈里斯巴尔 +

  • 恩里克里贝罗 +

  • 希曼舒阿瓦斯蒂

  • 洪少阳+

  • 伊戈尔法森 +

  • 贾拉兹贝 +

  • 杰布罗克门德尔

  • 吴建华 +

  • 贾斯丁陈23 +

  • 路易斯波托克

  • 马科斯鲁兰 +

  • 迈克985

  • nicolab100 +

  • 恩普拉德

  • 恩苏雷什+

  • 奥蒂普

  • 帕贾奇特 +

  • 拉吉亚尔2 +

  • 拉蒂贾斯 +

  • 真实领先+

  • 罗巴克利 +

  • saurav2608 +

  • 侧眼 +

  • 西克达尔1

  • 斯文哈里斯+

  • 苏拜+

  • 测试者 +

  • 那整齐

  • tmnhat2001

  • 托马斯卡西迪 +

  • 汤姆尼普

  • 礼帽-123

  • vkk800+

  • 赢路+

  • ym-佩特 +

  • 伊胡克 +

  • yw公园1 +

  • 泽特林

  • 遮遮润+