pandas DataFrame的本质

时间:2014-12-09 08:53:19

标签: python pandas

作为my question on mixed types in a column的后续内容:

我可以将DataFrame视为列列表还是行列表?

在前一种情况下,这意味着(最佳地)每列必须是同质的(按类型),不同的列可以是不同的类型。后一种情况表明,每一行都是类型齐全的。

对于文档:

  

DataFrame是一个二维标签数据结构,其中包含可能不同类型的列。

这意味着DataFrame是一个列列表。

是否意味着向DataFrame追加一行比追加一列更贵?

2 个答案:

答案 0 :(得分:6)

您完全正确,可以将DataFrame视为列列表,或者更多(有序)列词典(请参阅此处explanation)。

实际上,每列必须是同类的,不同的列可以是不同的类型。但是通过使用object dtype,您仍然可以在一列中保存不同类型的对象(尽管不建议分开用于例如字符串)。
为了说明,如果您询问DataFrame的数据类型,则会获得每列的dtype:

In [2]: df = pd.DataFrame({'int_col':[0,1,2], 'float_col':[0.0,1.1,2.5], 'bool_col':[True, False, True]})

In [3]: df.dtypes
Out[3]:
bool_col        bool
float_col    float64
int_col        int64
dtype: object

在内部,值存储为相同类型的块。每列或相同类型的列集合都存储在单独的数组中。

这确实意味着追加一行更加昂贵。通常,附加多个单行并不是一个好主意:例如,更好地预分配要填充的空数据帧,或者将新行/列放在列表中并一次性连接它们。 请参阅concat/append docs末尾的注释(在第一小节&#34之前;在其他轴上设置逻辑")。

答案 1 :(得分:1)

解决这个问题:向 DataFrame 添加行是否比添加列更昂贵? 我们需要考虑各种因素,但最重要的是Pandas Dataframe内部的物理数据布局。

简短而天真的答案: 如果表(又名 DataFrame)存储在逐列物理布局中,那么添加或获取列比使用行更快;如果表以行物理布局存储,则是另一种方式。通常,默认的 Pandas DataFrame 以列方式存储(但并非一直)。所以一般来说,向 DataFrame 追加一行确实比追加一列更昂贵。您可以将 Pandas DataFrame 的性质视为列的字典。

更长的答案: Pandas 需要选择一种方式来安排内存中表格的内部布局(例如一个 10 行 2 列的 Dataframe)。最常见的两种方法是按列和按行。

Pandas 建立在 Numpy 之上,DataFrame 和 Seires 建立在 Numpy Array 之上。但是请注意,尽管 Numpy Array 内部按行存储在内存中,但 Pandas DataFrame 并非如此。 DataFrame 的存储方式取决于它的启动方式,参见这篇文章:https://krbnite.github.io/Memory-Efficient-Windowing-of-Time-Series-Data-in-Python-2-NumPy-Arrays-vs-Pandas-DataFrames/

Pandas 大部分时间采用列式布局实际上是很自然的,因为 Pandas 被设计为一种数据分析工具,它更依赖于面向列的操作而不是面向行的操作。参见https://www.stitchdata.com/columnardatabase/

最后,问题的答案向 DataFrame 添加行比添加列更昂贵吗?还取决于缓存、预取等。因此,这是一个相当复杂的问题并且可能取决于特定的运行时条件。但最重要的因素是数据布局。


熊猫作者的回答

Pandas 的作者实际上在他们的设计文档中提到了这一点。参见https://github.com/pydata/pandas-design/blob/master/source/internal-architecture.rst#what-is-blockmanager-and-why-does-it-exist

<块引用>

因此,要在全数字 DataFrame 上执行任何面向行的操作,pandas 将所有列连接在一起(使用 numpy.vstack 或 numpy.hstack) 然后使用数组广播或 ndarray.sum 之类的方法 (结合 np.isnan 介意缺失数据)执行某些 操作。

相关问题