常见问题解答 (FAQ)#

DataFrame 内存使用情况#

DataFrame (包括索引) 的内存使用情况会在调用 info() 时显示。配置选项 display.memory_usage (参见 the list of options 指定了在调用 DataFrame 方法时是否显示 info() 的内存使用情况。

例如,下面的 DataFrame 的内存使用情况在调用 info() 时会显示:

+ 符号表示实际内存使用可能更高, 因为 pandas 不计算 dtype=object 的列中值的内存使用。

传递 memory_usage='deep' 将启用更准确的内存使用报告,该报告能计算出包含对象的完整使用情况。这是可选的,因为进行更深入的内省可能会非常耗时。

默认情况下,显示选项设置为 True,但可以通过在调用 info() 时传递 memory_usage 参数来显式覆盖。

通过调用 memory_usage() 方法可以找到每列的内存使用情况。这将返回一个 Series ,其索引是列名,内存使用情况用字节表示。对于上面的 DataFrame ,可以使用 memory_usage() 方法找到每列的内存使用情况和总内存使用情况:

默认情况下,返回的 DataFrame 中会显示 Series 索引的内存使用情况,可以通过传递 index=False 参数来抑制显示索引的内存使用情况:

info() 方法显示的内存使用情况利用 memory_usage() 方法来确定 DataFrame 的内存使用情况,同时将输出格式化为人类可读的单位 (基于 2 的表示法;即 1KB = 1024 字节)。

另请参阅 Categorical Memory Usage

在 pandas 中使用 if/truth 语句#

pandas 遵循 NumPy 的约定,当您尝试将某物转换为 bool 时会引发错误。这发生在 if 语句中,或者在使用布尔运算:andornot 时。以下代码的结果尚不清楚:

>>> if pd.Series([False, True, False]):
...     pass

应该为 True,因为它不是零长度,还是 False,因为它包含 False 值?这不清楚,因此 pandas 会引发 ValueError

您需要明确选择如何处理 DataFrame ,例如,使用 any()all()empty() 。或者,您可能想比较 pandas 对象是否为 None

以下是检查是否任何值为 True 的方法:

按位布尔值#

Bitwise boolean operators like == and != return a boolean Series which performs an element-wise comparison when compared to a scalar.

有关更多示例,请参阅 boolean comparisons

使用 in 运算符#

Series 使用 Python 的 in 运算符会测试 索引 中的成员资格,而不是值中的成员资格。

如果此行为让您感到惊讶,请记住,对 Python 字典使用 in 是测试键而不是值,而 Series 具有字典的类似行为。要测试值中的成员资格,请使用 isin() 方法:

对于 DataFrame ,同样,in 应用于列轴,测试列名列表中的成员资格。

使用用户定义函数 (UDF) 方法进行变异#

本节适用于接受 UDF 的 pandas 方法。特别是 DataFrame.apply()DataFrame.aggregate()DataFrame.transform()DataFrame.filter() 方法。

在编程中,一个普遍的规则是,不应该在迭代容器时修改它。修改会使迭代器失效,导致意外行为。考虑以下示例:

人们大概会认为结果是“[1, 3, 5]”。当使用接受 UDF(用户定义函数)的 pandas 方法时,pandas 内部通常会迭代 DataFrame 或其他 pandas 对象。因此,如果 UDF 修改(更改)了 DataFrame ,就可能出现意外行为。

下面是使用 DataFrame.apply() 的类似示例:

为了解决这个问题,可以创建一个副本,这样修改就不会应用于正在迭代的容器。

NumPy 类型的缺失值表示#

np.nan 作为 NumPy 类型的 NA 表示#

由于 NumPy 和 Python 在底层缺乏对 NA``(缺失)的支持,``NA 本可以这样表示:

  • 掩码数组 解决方案:一个数据数组和一个布尔值数组,指示某个值是否存在或缺失。

  • 使用特殊的哨兵值、位模式或一组哨兵值来表示跨数据类型的 NA

选择了特殊值 np.nan``(Not-A-Number,非数字)作为 NumPy 类型的 ``NA 值,并且存在 DataFrame.isna()DataFrame.notna() 等 API 函数,可以跨数据类型用于检测 NA 值。然而,这个选择有一个缺点,即会将缺失的整数数据强制转换为浮点类型,如 整数 NA 支持 所示。

NumPy 类型的 NA 类型提升#

当通过 Series 或其他方式将 NA 引入现有 DataFramereindex() 时,布尔类型和整数类型将被提升到不同的 dtype 以存储 NA。提升总结在此表中:

类型类

用于存储 NA 的提升 dtype

floating

无变化

object

无变化

integer

转换为 float64

boolean

转换为 object

整数 NA 支持#

由于 NumPy 从根本上缺乏高性能的 NA 支持,主要的牺牲是无法在整数数组中表示 NA。例如:

这种权衡主要是出于内存和性能的考虑,并且也为了使生成的 Series 继续保持“数值型”。

如果您需要表示可能包含缺失值的整数,请使用 pandas 或 pyarrow 提供的可为空整数扩展 dtype 之一

更多信息请参见 可空整数数据类型pandas 可以利用 PyArrow 来扩展功能并提高各种 API 的性能。这包括:

为什么不让 NumPy 像 R 一样?#

许多人建议 NumPy 应该直接模仿在更专业的统计编程语言 R 中存在的 NA 支持。部分原因是 NumPy type hierarchy

相比之下,R 语言只有少数内置数据类型:“integer”、“numeric”(浮点数)、“character”和“boolean”。 NA 类型是通过为每种类型保留特殊的位模式来作为缺失值来实现的。虽然这对于完整的 NumPy 类型层级结构来说是可行的,但这将是一个更大的权衡(特别是对于 8 位和 16 位数据类型)和实现上的挑战。

然而,通过使用掩码 NumPy 类型,如 Int64Dtype 或 PyArrow 类型(ArrowDtype ),现在可以获得 R 的 NA 语义。

与 NumPy 的区别#

对于 SeriesDataFrame 对象,var() 使用 N-1 进行归一化,以产生 unbiased estimates of the population variance ,而 NumPy 的 numpy.var() 使用 N 进行归一化,衡量的是样本的方差。请注意,cov() 在 pandas 和 NumPy 中都使用 N-1 进行归一化。

线程安全#

pandas 不是 100% 线程安全的。已知的与 copy() 方法相关的问题。如果您在多线程之间共享 DataFrame 对象并进行大量复制操作,我们建议在发生数据复制的线程内部使用锁。

有关更多信息,请参阅`this link <https://stackoverflow.com/questions/13592618/python-pandas-dataframe-thread-safe>`__ 。

字节序问题#

Occasionally you may have to deal with data that were created on a machine with a different byte order than the one on which you are running Python. A common symptom of this issue is an error like:

Traceback
    ...
ValueError: Big-endian buffer not supported on little-endian compiler

要解决此问题,您应该在将底层 NumPy 数组传递给 SeriesDataFrame 构造函数*之前*,使用类似以下方法将其转换为本地系统字节序:

有关更多详细信息,请参阅`the NumPy documentation on byte order <https://numpy.org/doc/stable/user/basics.byteswapping.html>`__ 。