Pandas 2.2 中文官方教程和指南(十一·一)(1)

简介: Pandas 2.2 中文官方教程和指南(十一·一)

PyArrow 功能

原文:pandas.pydata.org/docs/user_guide/pyarrow.html

pandas 可以利用PyArrow来扩展功能并改善各种 API 的性能。这包括:

  • 与 NumPy 相比,拥有更广泛的数据类型
  • 对所有数据类型支持缺失数据(NA)
  • 高性能 IO 读取器集成
  • 便于与基于 Apache Arrow 规范的其他数据框架库(例如 polars、cuDF)进行互操作性

要使用此功能,请确保您已经安装了最低支持的 PyArrow 版本。

数据结构集成

一个SeriesIndexDataFrame的列可以直接由pyarrow.ChunkedArray支持,这类似于 NumPy 数组。要从主要的 pandas 数据结构构造这些,您可以在dtype参数中传入类型后跟[pyarrow]的字符串,例如"int64[pyarrow]"

In [1]: ser = pd.Series([-1.5, 0.2, None], dtype="float32[pyarrow]")
In [2]: ser
Out[2]: 
0    -1.5
1     0.2
2    <NA>
dtype: float[pyarrow]
In [3]: idx = pd.Index([True, None], dtype="bool[pyarrow]")
In [4]: idx
Out[4]: Index([True, <NA>], dtype='bool[pyarrow]')
In [5]: df = pd.DataFrame([[1, 2], [3, 4]], dtype="uint64[pyarrow]")
In [6]: df
Out[6]: 
 0  1
0  1  2
1  3  4 

注意

字符串别名"string[pyarrow]"映射到pd.StringDtype("pyarrow"),这与指定dtype=pd.ArrowDtype(pa.string())不等效。通常,对数据的操作行为会类似,除了pd.StringDtype("pyarrow")可以返回基于 NumPy 的可空类型,而pd.ArrowDtype(pa.string())将返回ArrowDtype

In [7]: import pyarrow as pa
In [8]: data = list("abc")
In [9]: ser_sd = pd.Series(data, dtype="string[pyarrow]")
In [10]: ser_ad = pd.Series(data, dtype=pd.ArrowDtype(pa.string()))
In [11]: ser_ad.dtype == ser_sd.dtype
Out[11]: False
In [12]: ser_sd.str.contains("a")
Out[12]: 
0     True
1    False
2    False
dtype: boolean
In [13]: ser_ad.str.contains("a")
Out[13]: 
0     True
1    False
2    False
dtype: bool[pyarrow] 

对于接受参数的 PyArrow 类型,您可以将带有这些参数的 PyArrow 类型传入ArrowDtype以在dtype参数中使用。

In [14]: import pyarrow as pa
In [15]: list_str_type = pa.list_(pa.string())
In [16]: ser = pd.Series([["hello"], ["there"]], dtype=pd.ArrowDtype(list_str_type))
In [17]: ser
Out[17]: 
0    ['hello']
1    ['there']
dtype: list<item: string>[pyarrow] 
In [18]: from datetime import time
In [19]: idx = pd.Index([time(12, 30), None], dtype=pd.ArrowDtype(pa.time64("us")))
In [20]: idx
Out[20]: Index([12:30:00, <NA>], dtype='time64[us][pyarrow]') 
In [21]: from decimal import Decimal
In [22]: decimal_type = pd.ArrowDtype(pa.decimal128(3, scale=2))
In [23]: data = [[Decimal("3.19"), None], [None, Decimal("-1.23")]]
In [24]: df = pd.DataFrame(data, dtype=decimal_type)
In [25]: df
Out[25]: 
 0      1
0  3.19   <NA>
1  <NA>  -1.23 

如果您已经有一个pyarrow.Arraypyarrow.ChunkedArray,您可以将其传入arrays.ArrowExtensionArray以构造相关的SeriesIndexDataFrame对象。

In [26]: pa_array = pa.array(
 ....:    [{"1": "2"}, {"10": "20"}, None],
 ....:    type=pa.map_(pa.string(), pa.string()),
 ....: )
 ....: 
In [27]: ser = pd.Series(pd.arrays.ArrowExtensionArray(pa_array))
In [28]: ser
Out[28]: 
0      [('1', '2')]
1    [('10', '20')]
2              <NA>
dtype: map<string, string>[pyarrow] 

要从SeriesIndex中检索一个 pyarrow pyarrow.ChunkedArray,您可以在SeriesIndex上调用 pyarrow 数组构造函数。

In [29]: ser = pd.Series([1, 2, None], dtype="uint8[pyarrow]")
In [30]: pa.array(ser)
Out[30]: 
<pyarrow.lib.UInt8Array object at 0x7ff2a2968400>
[
 1,
 2,
 null
]
In [31]: idx = pd.Index(ser)
In [32]: pa.array(idx)
Out[32]: 
<pyarrow.lib.UInt8Array object at 0x7ff2a2968460>
[
 1,
 2,
 null
] 

要将 pyarrow.Table 转换为 DataFrame,您可以使用 types_mapper=pd.ArrowDtype 调用 pyarrow.Table.to_pandas() 方法。

In [33]: table = pa.table([pa.array([1, 2, 3], type=pa.int64())], names=["a"])
In [34]: df = table.to_pandas(types_mapper=pd.ArrowDtype)
In [35]: df
Out[35]: 
 a
0  1
1  2
2  3
In [36]: df.dtypes
Out[36]: 
a    int64[pyarrow]
dtype: object 

操作

PyArrow 数据结构集成是通过 pandas 的 ExtensionArray 接口 实现的;因此,在 pandas API 中集成了此接口的地方存在支持的功能。此外,当可用时,此功能通过 PyArrow compute functions 加速。这包括:

  • 数值聚合
  • 数值运算
  • 数值舍入
  • 逻辑和比较函数
  • 字符串功能
  • 日期时间功能

以下只是一些由本机 PyArrow 计算函数加速的操作示例。

In [37]: import pyarrow as pa
In [38]: ser = pd.Series([-1.545, 0.211, None], dtype="float32[pyarrow]")
In [39]: ser.mean()
Out[39]: -0.6669999808073044
In [40]: ser + ser
Out[40]: 
0    -3.09
1    0.422
2     <NA>
dtype: float[pyarrow]
In [41]: ser > (ser + 1)
Out[41]: 
0    False
1    False
2     <NA>
dtype: bool[pyarrow]
In [42]: ser.dropna()
Out[42]: 
0   -1.545
1    0.211
dtype: float[pyarrow]
In [43]: ser.isna()
Out[43]: 
0    False
1    False
2     True
dtype: bool
In [44]: ser.fillna(0)
Out[44]: 
0   -1.545
1    0.211
2      0.0
dtype: float[pyarrow] 
In [45]: ser_str = pd.Series(["a", "b", None], dtype=pd.ArrowDtype(pa.string()))
In [46]: ser_str.str.startswith("a")
Out[46]: 
0     True
1    False
2     <NA>
dtype: bool[pyarrow] 
In [47]: from datetime import datetime
In [48]: pa_type = pd.ArrowDtype(pa.timestamp("ns"))
In [49]: ser_dt = pd.Series([datetime(2022, 1, 1), None], dtype=pa_type)
In [50]: ser_dt.dt.strftime("%Y-%m")
Out[50]: 
0    2022-01
1       <NA>
dtype: string[pyarrow] 

I/O 读取

PyArrow 还提供了已集成到几个 pandas IO 读取器中的 IO 读取功能。以下函数提供了一个 engine 关键字,可以调度到 PyArrow 以加速从 IO 源读取。

  • read_csv()
  • read_json()
  • read_orc()
  • read_feather()
In [51]: import io
In [52]: data = io.StringIO("""a,b,c
 ....:   1,2.5,True
 ....:   3,4.5,False
 ....: """)
 ....: 
In [53]: df = pd.read_csv(data, engine="pyarrow")
In [54]: df
Out[54]: 
 a    b      c
0  1  2.5   True
1  3  4.5  False 

默认情况下,这些函数和所有其他 IO 读取器函数返回 NumPy 支持的数据。这些读取器可以通过指定参数 dtype_backend="pyarrow" 返回 PyArrow 支持的数据。读取器不需要设置 engine="pyarrow" 来必然返回 PyArrow 支持的数据。

In [55]: import io
In [56]: data = io.StringIO("""a,b,c,d,e,f,g,h,i
 ....:    1,2.5,True,a,,,,,
 ....:    3,4.5,False,b,6,7.5,True,a,
 ....: """)
 ....: 
In [57]: df_pyarrow = pd.read_csv(data, dtype_backend="pyarrow")
In [58]: df_pyarrow.dtypes
Out[58]: 
a     int64[pyarrow]
b    double[pyarrow]
c      bool[pyarrow]
d    string[pyarrow]
e     int64[pyarrow]
f    double[pyarrow]
g      bool[pyarrow]
h    string[pyarrow]
i      null[pyarrow]
dtype: object 

还有几个非 IO 读取器函数也可以使用 dtype_backend 参数返回 PyArrow 支持的数据,包括:

  • to_numeric()
  • DataFrame.convert_dtypes()
  • Series.convert_dtypes()

数据结构集成

一个SeriesIndexDataFrame的列可以直接由一个类似于 NumPy 数组的pyarrow.ChunkedArray支持,要从主要的 pandas���据结构构造这些对象,您可以在类型后面加上[pyarrow]的字符串,例如"int64[pyarrow]"传递给dtype参数

In [1]: ser = pd.Series([-1.5, 0.2, None], dtype="float32[pyarrow]")
In [2]: ser
Out[2]: 
0    -1.5
1     0.2
2    <NA>
dtype: float[pyarrow]
In [3]: idx = pd.Index([True, None], dtype="bool[pyarrow]")
In [4]: idx
Out[4]: Index([True, <NA>], dtype='bool[pyarrow]')
In [5]: df = pd.DataFrame([[1, 2], [3, 4]], dtype="uint64[pyarrow]")
In [6]: df
Out[6]: 
 0  1
0  1  2
1  3  4 

注意

字符串别名"string[pyarrow]"映射到pd.StringDtype("pyarrow"),这与指定dtype=pd.ArrowDtype(pa.string())不等效。通常,对数据的操作行为类似,除了pd.StringDtype("pyarrow")可以返回基于 NumPy 的可空类型,而pd.ArrowDtype(pa.string())将返回ArrowDtype

In [7]: import pyarrow as pa
In [8]: data = list("abc")
In [9]: ser_sd = pd.Series(data, dtype="string[pyarrow]")
In [10]: ser_ad = pd.Series(data, dtype=pd.ArrowDtype(pa.string()))
In [11]: ser_ad.dtype == ser_sd.dtype
Out[11]: False
In [12]: ser_sd.str.contains("a")
Out[12]: 
0     True
1    False
2    False
dtype: boolean
In [13]: ser_ad.str.contains("a")
Out[13]: 
0     True
1    False
2    False
dtype: bool[pyarrow] 

对于接受参数的 PyArrow 类型,您可以将带有这些参数的 PyArrow 类型传递给ArrowDtype以在dtype参数中使用。

In [14]: import pyarrow as pa
In [15]: list_str_type = pa.list_(pa.string())
In [16]: ser = pd.Series([["hello"], ["there"]], dtype=pd.ArrowDtype(list_str_type))
In [17]: ser
Out[17]: 
0    ['hello']
1    ['there']
dtype: list<item: string>[pyarrow] 
In [18]: from datetime import time
In [19]: idx = pd.Index([time(12, 30), None], dtype=pd.ArrowDtype(pa.time64("us")))
In [20]: idx
Out[20]: Index([12:30:00, <NA>], dtype='time64[us][pyarrow]') 
In [21]: from decimal import Decimal
In [22]: decimal_type = pd.ArrowDtype(pa.decimal128(3, scale=2))
In [23]: data = [[Decimal("3.19"), None], [None, Decimal("-1.23")]]
In [24]: df = pd.DataFrame(data, dtype=decimal_type)
In [25]: df
Out[25]: 
 0      1
0  3.19   <NA>
1  <NA>  -1.23 

如果您已经有一个pyarrow.Arraypyarrow.ChunkedArray,您可以将其传递给arrays.ArrowExtensionArray以构造相关的SeriesIndexDataFrame对象。

In [26]: pa_array = pa.array(
 ....:    [{"1": "2"}, {"10": "20"}, None],
 ....:    type=pa.map_(pa.string(), pa.string()),
 ....: )
 ....: 
In [27]: ser = pd.Series(pd.arrays.ArrowExtensionArray(pa_array))
In [28]: ser
Out[28]: 
0      [('1', '2')]
1    [('10', '20')]
2              <NA>
dtype: map<string, string>[pyarrow] 

要从SeriesIndex中检索一个 pyarrow pyarrow.ChunkedArray,您可以在SeriesIndex上调用 pyarrow 数组构造函数。

In [29]: ser = pd.Series([1, 2, None], dtype="uint8[pyarrow]")
In [30]: pa.array(ser)
Out[30]: 
<pyarrow.lib.UInt8Array object at 0x7ff2a2968400>
[
 1,
 2,
 null
]
In [31]: idx = pd.Index(ser)
In [32]: pa.array(idx)
Out[32]: 
<pyarrow.lib.UInt8Array object at 0x7ff2a2968460>
[
 1,
 2,
 null
] 

要将pyarrow.Table转换为DataFrame,您可以使用types_mapper=pd.ArrowDtype调用pyarrow.Table.to_pandas()方法。

In [33]: table = pa.table([pa.array([1, 2, 3], type=pa.int64())], names=["a"])
In [34]: df = table.to_pandas(types_mapper=pd.ArrowDtype)
In [35]: df
Out[35]: 
 a
0  1
1  2
2  3
In [36]: df.dtypes
Out[36]: 
a    int64[pyarrow]
dtype: object 

操作

PyArrow 数据结构集成是通过 pandas 的ExtensionArray 接口实现的;因此,在 pandas API 中集成了此接口的地方存在支持的功能。此外,此功能在可用时通过 PyArrow compute functions加速。这包括:

  • 数值聚合
  • 数值运算
  • 数值舍入
  • 逻辑和比较函数
  • 字符串功能
  • 日期时间功能

以下只是一些由本机 PyArrow 计算函数加速的操作示例。

In [37]: import pyarrow as pa
In [38]: ser = pd.Series([-1.545, 0.211, None], dtype="float32[pyarrow]")
In [39]: ser.mean()
Out[39]: -0.6669999808073044
In [40]: ser + ser
Out[40]: 
0    -3.09
1    0.422
2     <NA>
dtype: float[pyarrow]
In [41]: ser > (ser + 1)
Out[41]: 
0    False
1    False
2     <NA>
dtype: bool[pyarrow]
In [42]: ser.dropna()
Out[42]: 
0   -1.545
1    0.211
dtype: float[pyarrow]
In [43]: ser.isna()
Out[43]: 
0    False
1    False
2     True
dtype: bool
In [44]: ser.fillna(0)
Out[44]: 
0   -1.545
1    0.211
2      0.0
dtype: float[pyarrow] 
In [45]: ser_str = pd.Series(["a", "b", None], dtype=pd.ArrowDtype(pa.string()))
In [46]: ser_str.str.startswith("a")
Out[46]: 
0     True
1    False
2     <NA>
dtype: bool[pyarrow] 
In [47]: from datetime import datetime
In [48]: pa_type = pd.ArrowDtype(pa.timestamp("ns"))
In [49]: ser_dt = pd.Series([datetime(2022, 1, 1), None], dtype=pa_type)
In [50]: ser_dt.dt.strftime("%Y-%m")
Out[50]: 
0    2022-01
1       <NA>
dtype: string[pyarrow] 

I/O 读取

PyArrow 还提供了已集成到几个 pandas IO 读取器中的 IO 读取功能。以下函数提供了一个engine关键字,可以调度到 PyArrow 以加速从 IO 源读取。

  • read_csv()
  • read_json()
  • read_orc()
  • read_feather()
In [51]: import io
In [52]: data = io.StringIO("""a,b,c
 ....:   1,2.5,True
 ....:   3,4.5,False
 ....: """)
 ....: 
In [53]: df = pd.read_csv(data, engine="pyarrow")
In [54]: df
Out[54]: 
 a    b      c
0  1  2.5   True
1  3  4.5  False 

默认情况下,这些函数和所有其他 IO 读取函数返回 NumPy 支持的数据。通过指定参数dtype_backend="pyarrow",这些读取器可以返回 PyArrow 支持的数据。读取器不需要设置engine="pyarrow"来必然返回 PyArrow 支持的数据。

In [55]: import io
In [56]: data = io.StringIO("""a,b,c,d,e,f,g,h,i
 ....:    1,2.5,True,a,,,,,
 ....:    3,4.5,False,b,6,7.5,True,a,
 ....: """)
 ....: 
In [57]: df_pyarrow = pd.read_csv(data, dtype_backend="pyarrow")
In [58]: df_pyarrow.dtypes
Out[58]: 
a     int64[pyarrow]
b    double[pyarrow]
c      bool[pyarrow]
d    string[pyarrow]
e     int64[pyarrow]
f    double[pyarrow]
g      bool[pyarrow]
h    string[pyarrow]
i      null[pyarrow]
dtype: object 

还有一些非 IO 读取函数也可以使用dtype_backend参数返回 PyArrow 支持的数据,包括:

  • to_numeric()
  • DataFrame.convert_dtypes()
  • Series.convert_dtypes()

索引和选择数据

原文:pandas.pydata.org/docs/user_guide/indexing.html

pandas 对象中的轴标签信息具有多种用途:

  • 使用已知指标标识数据(即提供 元数据),对于分析、可视化和交互式控制台显示非常重要。
  • 启用自动和明确的数据对齐。
  • 允许直观地获取和设置数据集的子集。

在本节中,我们将重点放在最后一点上:即如何切片、切块和通常获取和设置 pandas 对象的子集。���要关注将放在 Series 和 DataFrame 上,因为它们在这个领域接受了更多的开发关注。

注意

Python 和 NumPy 索引运算符 [] 和属性运算符 . 提供了对 pandas 数据结构的快速简便访问,适用于各种用例。这使得交互式工作变得直观,因为如果你已经知道如何处理 Python 字典和 NumPy 数组,那么学习成本很低。然而,由于要访问的数据类型事先未知,直接使用标准运算符存在一些优化限制。对于生产代码,我们建议您利用本章节中提供的优化的 pandas 数据访问方法。

警告

对于设置操作,返回的是副本还是引用,可能取决于上下文。有时这被称为 chained assignment,应该避免。请参阅返回视图与副本。

在 MultiIndex / 高级索引中查看 MultiIndex 和更高级的索引文档。

在食谱中查看一些高级策略。

不同的索引选择

为了支持更明确的基于位置的索引,对象选择已经增加了一些用户请求的内容。pandas 现在支持三种类型的多轴索引。

  • .loc 主要基于标签,但也可以与布尔数组一起使用。当未找到项目时,.loc 会引发 KeyError。允许的输入包括:
  • 单个标签,例如 5'a'(请注意,5 被解释为索引的 标签。这种用法不是索引上的整数位置。)。

  • 一个标签列表或数组 ['a', 'b', 'c']

  • 一个带有标签 'a':'f' 的切片对象(请注意,与通常的 Python 切片相反,开始和停止都包括在内,当存在于索引中时!请参阅使用标签切片和端点是包含的。)

  • 布尔数组(任何 NA 值将被视为 False)。

  • 一个带有一个参数(调用的 Series 或 DataFrame)的 callable 函数,并返回用于索引的有效输出(上述之一)。

  • 一个包含上述输入之一的行(和列)索引的元组。
  • 在按标签选择中查看更多信息。
  • .iloc主要基于整数位置(从轴的0length-1),但也可以与布尔数组一起使用。如果请求的索引器超出范围,.iloc将引发IndexError,除了切片索引器允许超出范围索引(这符合 Python/NumPy 的切片语义)。允许的输入为:
  • 一个整数,例如5

  • 整数列表或数组[4, 3, 0]

  • 一个包含整数1:7的切片对象。

  • 布尔数组(任何NA值将被视为False)。

  • 一个带有一个参数(调用的 Series 或 DataFrame)的callable函数,并返回用于索引的有效输出(上述之一)。

  • 一个包含行(和列)索引的元组,其元素是上述输入之一。
  • 查看更多内容请参考按位置选择,高级索引和高级分层。
  • .loc.iloc,以及[]索引可以接受callable作为索引器。查看更多内容请参考按 callable 选择。
    注意
    将元组键解构为行(和列)索引发生在调用可调用函数之前,因此您不能从可调用函数返回元组以同时索引���和列。

从具有多轴选择的对象获取值使用以下表示法(以.loc为例,但以下内容也适用于.iloc)。任何轴访问器都可以是空切片:。规范中省略的轴被假定为:,例如p.loc['a']等同于p.loc['a', :]

对象类型 索引器
Series s.loc[indexer]

| DataFrame | df.loc[row_indexer,column_indexer] | ## 基础知识

如在上一节介绍数据结构时提到的,使用[]进行索引(在 Python 中实现类行为的熟悉者称之为__getitem__)的主要功能是选择出低维度切片。下表显示了使用[]对 pandas 对象进行索引时的返回类型值:

对象类型 选择 返回值类型
Series series[label] 标量值
DataFrame frame[colname] 与 colname 对应的Series

这里我们构建一个简单的时间序列数据集,用于说明索引功能:

In [1]: dates = pd.date_range('1/1/2000', periods=8)
In [2]: df = pd.DataFrame(np.random.randn(8, 4),
 ...:                  index=dates, columns=['A', 'B', 'C', 'D'])
 ...: 
In [3]: df
Out[3]: 
 A         B         C         D
2000-01-01  0.469112 -0.282863 -1.509059 -1.135632
2000-01-02  1.212112 -0.173215  0.119209 -1.044236
2000-01-03 -0.861849 -2.104569 -0.494929  1.071804
2000-01-04  0.721555 -0.706771 -1.039575  0.271860
2000-01-05 -0.424972  0.567020  0.276232 -1.087401
2000-01-06 -0.673690  0.113648 -1.478427  0.524988
2000-01-07  0.404705  0.577046 -1.715002 -1.039268
2000-01-08 -0.370647 -1.157892 -1.344312  0.844885 

注意

除非特别说明,否则索引功能都不是特定于时间序列的。

因此,根据上述,我们可以使用[]进行最基本的索引:

In [4]: s = df['A']
In [5]: s[dates[5]]
Out[5]: -0.6736897080883706 

您可以传递一个列列表给[]以按顺序选择列。如果 DataFrame 中不包含某列,将引发异常。也可以以这种方式设置多个列:

In [6]: df
Out[6]: 
 A         B         C         D
2000-01-01  0.469112 -0.282863 -1.509059 -1.135632
2000-01-02  1.212112 -0.173215  0.119209 -1.044236
2000-01-03 -0.861849 -2.104569 -0.494929  1.071804
2000-01-04  0.721555 -0.706771 -1.039575  0.271860
2000-01-05 -0.424972  0.567020  0.276232 -1.087401
2000-01-06 -0.673690  0.113648 -1.478427  0.524988
2000-01-07  0.404705  0.577046 -1.715002 -1.039268
2000-01-08 -0.370647 -1.157892 -1.344312  0.844885
In [7]: df[['B', 'A']] = df[['A', 'B']]
In [8]: df
Out[8]: 
 A         B         C         D
2000-01-01 -0.282863  0.469112 -1.509059 -1.135632
2000-01-02 -0.173215  1.212112  0.119209 -1.044236
2000-01-03 -2.104569 -0.861849 -0.494929  1.071804
2000-01-04 -0.706771  0.721555 -1.039575  0.271860
2000-01-05  0.567020 -0.424972  0.276232 -1.087401
2000-01-06  0.113648 -0.673690 -1.478427  0.524988
2000-01-07  0.577046  0.404705 -1.715002 -1.039268
2000-01-08 -1.157892 -0.370647 -1.344312  0.844885 

您可能会发现这对于对一部分列应用变换(就地)很有用。

警告

当使用.loc设置SeriesDataFrame时,pandas 会对齐所有轴。

这不会修改df,因为列对齐是在赋值之前进行的。

In [9]: df[['A', 'B']]
Out[9]: 
 A         B
2000-01-01 -0.282863  0.469112
2000-01-02 -0.173215  1.212112
2000-01-03 -2.104569 -0.861849
2000-01-04 -0.706771  0.721555
2000-01-05  0.567020 -0.424972
2000-01-06  0.113648 -0.673690
2000-01-07  0.577046  0.404705
2000-01-08 -1.157892 -0.370647
In [10]: df.loc[:, ['B', 'A']] = df[['A', 'B']]
In [11]: df[['A', 'B']]
Out[11]: 
 A         B
2000-01-01 -0.282863  0.469112
2000-01-02 -0.173215  1.212112
2000-01-03 -2.104569 -0.861849
2000-01-04 -0.706771  0.721555
2000-01-05  0.567020 -0.424972
2000-01-06  0.113648 -0.673690
2000-01-07  0.577046  0.404705
2000-01-08 -1.157892 -0.370647 

交换列值的正确方式是使用原始值:

In [12]: df.loc[:, ['B', 'A']] = df[['A', 'B']].to_numpy()
In [13]: df[['A', 'B']]
Out[13]: 
 A         B
2000-01-01  0.469112 -0.282863
2000-01-02  1.212112 -0.173215
2000-01-03 -0.861849 -2.104569
2000-01-04  0.721555 -0.706771
2000-01-05 -0.424972  0.567020
2000-01-06 -0.673690  0.113648
2000-01-07  0.404705  0.577046
2000-01-08 -0.370647 -1.157892 

然而,当使用.iloc设置SeriesDataFrame时,pandas 不会对轴进行对齐,因为.iloc是按位置操作的。

这将修改df,因为在值分配之前未执行列对齐。

In [14]: df[['A', 'B']]
Out[14]: 
 A         B
2000-01-01  0.469112 -0.282863
2000-01-02  1.212112 -0.173215
2000-01-03 -0.861849 -2.104569
2000-01-04  0.721555 -0.706771
2000-01-05 -0.424972  0.567020
2000-01-06 -0.673690  0.113648
2000-01-07  0.404705  0.577046
2000-01-08 -0.370647 -1.157892
In [15]: df.iloc[:, [1, 0]] = df[['A', 'B']]
In [16]: df[['A','B']]
Out[16]: 
 A         B
2000-01-01 -0.282863  0.469112
2000-01-02 -0.173215  1.212112
2000-01-03 -2.104569 -0.861849
2000-01-04 -0.706771  0.721555
2000-01-05  0.567020 -0.424972
2000-01-06  0.113648 -0.673690
2000-01-07  0.577046  0.404705
2000-01-08 -1.157892 -0.370647 

属性访问

您可以直接访问Series上的索引或DataFrame上的列作为属性:

In [17]: sa = pd.Series([1, 2, 3], index=list('abc'))
In [18]: dfa = df.copy() 
In [19]: sa.b
Out[19]: 2
In [20]: dfa.A
Out[20]: 
2000-01-01   -0.282863
2000-01-02   -0.173215
2000-01-03   -2.104569
2000-01-04   -0.706771
2000-01-05    0.567020
2000-01-06    0.113648
2000-01-07    0.577046
2000-01-08   -1.157892
Freq: D, Name: A, dtype: float64 
In [21]: sa.a = 5
In [22]: sa
Out[22]: 
a    5
b    2
c    3
dtype: int64
In [23]: dfa.A = list(range(len(dfa.index)))  # ok if A already exists
In [24]: dfa
Out[24]: 
 A         B         C         D
2000-01-01  0  0.469112 -1.509059 -1.135632
2000-01-02  1  1.212112  0.119209 -1.044236
2000-01-03  2 -0.861849 -0.494929  1.071804
2000-01-04  3  0.721555 -1.039575  0.271860
2000-01-05  4 -0.424972  0.276232 -1.087401
2000-01-06  5 -0.673690 -1.478427  0.524988
2000-01-07  6  0.404705 -1.715002 -1.039268
2000-01-08  7 -0.370647 -1.344312  0.844885
In [25]: dfa['A'] = list(range(len(dfa.index)))  # use this form to create a new column
In [26]: dfa
Out[26]: 
 A         B         C         D
2000-01-01  0  0.469112 -1.509059 -1.135632
2000-01-02  1  1.212112  0.119209 -1.044236
2000-01-03  2 -0.861849 -0.494929  1.071804
2000-01-04  3  0.721555 -1.039575  0.271860
2000-01-05  4 -0.424972  0.276232 -1.087401
2000-01-06  5 -0.673690 -1.478427  0.524988
2000-01-07  6  0.404705 -1.715002 -1.039268
2000-01-08  7 -0.370647 -1.344312  0.844885 

警告

  • 只有当索引元素是有效的 Python 标识符时,才能使用此访问,例如s.1是不允许的。请参阅此处以获取有效标识符的解释
  • 如果属性与现有方法名称冲突,则该属性将不可用,例如s.min是不允许的,但s['min']是可能的。
  • 类似地,如果属性与以下列表中的任何一个冲突,则该属性将不可用:indexmajor_axisminor_axisitems
  • 在任何这些情况下,标准索引仍然有效,例如s['1']s['min']s['index']将访问相应的元素或列。

如果您在 IPython 环境中使用,还可以使用制表符补全来查看这些可访问的属性。

您还可以将dict分配给DataFrame的一行:

In [27]: x = pd.DataFrame({'x': [1, 2, 3], 'y': [3, 4, 5]})
In [28]: x.iloc[1] = {'x': 9, 'y': 99}
In [29]: x
Out[29]: 
 x   y
0  1   3
1  9  99
2  3   5 

您可以使用属性访问来修改 Series 的现有元素或 DataFrame 的列,但要小心;如果尝试使用属性访问创建新列,则会创建一个新属性而不是新列,并且会引发UserWarning

In [30]: df_new = pd.DataFrame({'one': [1., 2., 3.]})
In [31]: df_new.two = [4, 5, 6]
In [32]: df_new
Out[32]: 
 one
0  1.0
1  2.0
2  3.0 

切片范围

沿着任意轴切片范围的最稳健和一致的方法在按位置选择部分详细描述了.iloc方法。现在,我们解释使用[]运算符进行切片的语义。

对于 Series,语法与 ndarray 完全相同,返回值的切片和相应的标签:

In [33]: s[:5]
Out[33]: 
2000-01-01    0.469112
2000-01-02    1.212112
2000-01-03   -0.861849
2000-01-04    0.721555
2000-01-05   -0.424972
Freq: D, Name: A, dtype: float64
In [34]: s[::2]
Out[34]: 
2000-01-01    0.469112
2000-01-03   -0.861849
2000-01-05   -0.424972
2000-01-07    0.404705
Freq: 2D, Name: A, dtype: float64
In [35]: s[::-1]
Out[35]: 
2000-01-08   -0.370647
2000-01-07    0.404705
2000-01-06   -0.673690
2000-01-05   -0.424972
2000-01-04    0.721555
2000-01-03   -0.861849
2000-01-02    1.212112
2000-01-01    0.469112
Freq: -1D, Name: A, dtype: float64 

请注意,设置也有效:

In [36]: s2 = s.copy()
In [37]: s2[:5] = 0
In [38]: s2
Out[38]: 
2000-01-01    0.000000
2000-01-02    0.000000
2000-01-03    0.000000
2000-01-04    0.000000
2000-01-05    0.000000
2000-01-06   -0.673690
2000-01-07    0.404705
2000-01-08   -0.370647
Freq: D, Name: A, dtype: float64 

对于 DataFrame,在[]内部切片切片行。这在很大程度上是为了方便,因为这是一个常见的操作。

In [39]: df[:3]
Out[39]: 
 A         B         C         D
2000-01-01 -0.282863  0.469112 -1.509059 -1.135632
2000-01-02 -0.173215  1.212112  0.119209 -1.044236
2000-01-03 -2.104569 -0.861849 -0.494929  1.071804
In [40]: df[::-1]
Out[40]: 
 A         B         C         D
2000-01-08 -1.157892 -0.370647 -1.344312  0.844885
2000-01-07  0.577046  0.404705 -1.715002 -1.039268
2000-01-06  0.113648 -0.673690 -1.478427  0.524988
2000-01-05  0.567020 -0.424972  0.276232 -1.087401
2000-01-04 -0.706771  0.721555 -1.039575  0.271860
2000-01-03 -2.104569 -0.861849 -0.494929  1.071804
2000-01-02 -0.173215  1.212112  0.119209 -1.044236
2000-01-01 -0.282863  0.469112 -1.509059 -1.135632 


Pandas 2.2 中文官方教程和指南(十一·一)(2)https://developer.aliyun.com/article/1509861

相关文章
|
11月前
|
SQL 数据采集 数据挖掘
Pandas 教程
10月更文挑战第25天
214 2
|
存储 JSON 数据格式
Pandas 使用教程 CSV - CSV 转 JSON
Pandas 使用教程 CSV - CSV 转 JSON
131 0
|
JSON 数据格式 Python
Pandas 使用教程 JSON
Pandas 使用教程 JSON
146 0
|
SQL 数据采集 JSON
Pandas 使用教程 Series、DataFrame
Pandas 使用教程 Series、DataFrame
230 0
|
数据采集 存储 数据可视化
Pandas高级教程:数据清洗、转换与分析
Pandas是Python的数据分析库,提供Series和DataFrame数据结构及数据分析工具,便于数据清洗、转换和分析。本教程涵盖Pandas在数据清洗(如缺失值、重复值和异常值处理)、转换(数据类型转换和重塑)和分析(如描述性统计、分组聚合和可视化)的应用。通过学习Pandas,用户能更高效地处理和理解数据,为数据分析任务打下基础。
1365 3
|
存储 SQL 索引
Pandas 2.2 中文官方教程和指南(十一·二)(4)
Pandas 2.2 中文官方教程和指南(十一·二)
110 1
|
测试技术 索引 Python
Pandas 2.2 中文官方教程和指南(十一·二)(3)
Pandas 2.2 中文官方教程和指南(十一·二)
114 1
|
索引 Python
Pandas 2.2 中文官方教程和指南(十一·二)(2)
Pandas 2.2 中文官方教程和指南(十一·二)
87 1
|
索引 Python
Pandas 2.2 中文官方教程和指南(一)(4)
Pandas 2.2 中文官方教程和指南(一)
145 0
|
存储 SQL JSON
Pandas 2.2 中文官方教程和指南(一)(3)
Pandas 2.2 中文官方教程和指南(一)
201 0