【问题标题】:Strings in pandas dataframe from uproot来自uproot的pandas数据框中的字符串
【发布时间】:2019-11-19 15:15:17
【问题描述】:

在 Geant4 中使用输出 .root 文件的模拟,我很高兴发现了 uproot 包。

相信数据帧是我特定分析任务的最佳选择,我使用 uproot.pandas.df() 将 TTree 中的内容读入这样的数据帧。

不幸的是,这成为了瓶颈。虽然代码可以很好地处理所有数字输入,但处理字符串似乎是一个严重的问题。该文件很大,生成的帧有 2406703 行。

虽然此代码(Egammaz_eu 均为数字):

df = uproot.open('rootFile.root')['seco_tuple;1].pandas.df( ['Egamma','z_eu'])

平均需要 430 毫秒,包括已经包含字符串的一列:

df = uproot.open('rootFile.root')['seco_tuple;1].pandas.df( ['Name','Egamma','z_eu'])

将时间增加到近 3.5 秒。有一个带有字符串的第二列会使时间加倍。我还尝试过读取字典中的数据,然后将其传递给数据框。读取数据相当快,但将其传递到数据帧然后又很慢。

由于字符串显然会导致代码占用更多资源,所以我想知道字符串通常是否是数据帧的问题,或者这里的特定类型的字符串可能会有所不同?

我希望在这里得到一些进一步的了解,并可以尝试提供.root 文件以及 MWE,以防需要。

提前致谢!

【问题讨论】:

    标签: pandas uproot


    【解决方案1】:

    部分问题在于,用纯 Python 编写的 uproot 在性能上在 NumPy 处理得非常快的数字工作和任何涉及 Python 对象(如字符串)的工作之间存在明显分歧。在某些情况下,例如this one,我们可以选择将字符串视为数字数组,这对性能有很大帮助。

    另一部分是 Pandas 本身。 NumPy 的字符串效率很低,因为它们必须被填充到一个共同的长度——数据集中最长字符串的长度——因为 NumPy 只能处理直线数组。因此,Pandas 选择了一种不同的低效率:它将字符串作为 Python 对象,通过一个 NumPy 数组,其 dtypeobject(即指向 Python 对象的指针,而不是原始数字数据)。

    >>> import pandas, numpy
    >>> df = pandas.DataFrame({"column": ["one", "two", "three", "four", "five"]})
    >>> df
      column
    0    one
    1    two
    2  three
    3   four
    4   five
    >>> df.values
    array([['one'],
           ['two'],
           ['three'],
           ['four'],
           ['five']], dtype=object)
    

    当字符串只是标签时,Pandas 有一个“分类”dtype(不是 NumPy 的一部分!)用整数替换每个不同的字符串,因此它实际上是一个带有元数据的整数数组。

    >>> df["column"].astype("category")
    0      one
    1      two
    2    three
    3     four
    4     five
    Name: column, dtype: category
    Categories (5, object): [five, four, one, three, two]
    

    如果与字符串总数相比,您有少量不同的字符串(不是上面的情况),那么这会更快并且使用更少的内存。如果每个字符串都是唯一的,这只会使数据膨胀。

    也许 uproot 的 DataFrame 转换应该将一些字符串值分支读入“分类”dtype。这需要用户明确要求作为参数,因为它并不总是有用的。这样的事情会出现在uproot._connect._pandas.futures2df 函数中——如果有人愿意贡献,我会为此接受 PR。

    【讨论】:

    • 您好,非常感谢您的意见。似乎用DataFrame 处理这个数据集并不能提供有效的解决方案。在不改变uproot 将数据读取到DataFrame 的方式的情况下,速度或内存使用率似乎没有任何提高,至少就我(诚然有限的)知识而言......
    猜你喜欢
    • 2018-05-04
    • 2016-02-10
    • 2014-09-28
    • 1970-01-01
    • 2018-06-05
    • 2019-10-30
    • 2019-07-15
    • 2020-12-26
    • 1970-01-01
    相关资源
    最近更新 更多