Python 哪一个数据帧更好:超长数据帧与结构糟糕的列表数据帧

Python 哪一个数据帧更好:超长数据帧与结构糟糕的列表数据帧,python,pandas,dataframe,Python,Pandas,Dataframe,我一直在尝试通过n-gram标记文本来实现NLP。我必须分别按标签A和B计算每个n-gram出现的次数 然而,我必须在将一个长列表放入一个列与获取一个很长的数据帧之间做出选择,我不确定哪种结构优于另一种结构 顺便说一句,在数据帧的一列中包含列表是一种糟糕的结构,因为您很难使用pandas操作获得任何有用的信息,例如获取多个列表中某个项目的频率(发生率)。而且,即使可能,也需要更多的计算来完成任何任务 但是,我知道数据帧太长会占用大量RAM,如果数据太大而无法放入RAM,甚至可能会杀死其他进程。我

我一直在尝试通过n-gram标记文本来实现NLP。我必须分别按标签
A
B
计算每个n-gram出现的次数

然而,我必须在将一个长列表放入一个列与获取一个很长的数据帧之间做出选择,我不确定哪种结构优于另一种结构

顺便说一句,在数据帧的一列中包含列表是一种糟糕的结构,因为您很难使用pandas操作获得任何有用的信息,例如获取多个列表中某个项目的频率(发生率)。而且,即使可能,也需要更多的计算来完成任何任务

但是,我知道数据帧太长会占用大量RAM,如果数据太大而无法放入RAM,甚至可能会杀死其他进程。我当然不想处于这种情况

所以现在我必须做出选择。我想做的是根据每一个ngram项目的标签来计算它的出现次数

例如,(数据帧如下所示)

我想这和我电脑的规格有关

CPU:i3-6100

内存:16GB

GPU:不适用

数据帧1:

+------------+-------------------------------------------+-------+
|    DATE    |                   NGRAM                   | LABEL |
+------------+-------------------------------------------+-------+
| 2019-02-01 | [hey, hey, reddit, reddit, learn, python] | A     |
| 2019-02-02 | [python, reddit, pandas, dataframe]       | B     |
| 2019-02-03 | [python, reddit, ask, learn]              | A     |
+------------+-------------------------------------------+-------+
数据帧2:

+------------+-----------+-------+
|    DATE    |   NGRAM   | LABEL |
+------------+-----------+-------+
| 2019-02-01 | hey       | A     |
| 2019-02-01 | hey       | A     |
| 2019-02-01 | reddit    | A     |
| 2019-02-01 | reddit    | A     |
| 2019-02-01 | learn     | A     |
| 2019-02-01 | python    | A     |
| 2019-02-02 | python    | B     |
| 2019-02-02 | reddit    | B     |
| 2019-02-02 | pandas    | B     |
| 2019-02-02 | dataframe | B     |
| 2019-02-03 | python    | A     |
| 2019-02-03 | reddit    | A     |
| 2019-02-03 | ask       | A     |
| 2019-02-03 | learn     | A     |
+------------+-----------+-------+

正如您所提到的,在数据帧的列中有一个列表是一个糟糕的结构,长格式的数据帧是首选。让我试着从几个方面回答这个问题:

  • 增加了数据操作的复杂性&缺少对类似列表的列的本机支持函数
  • 对于类似列表的列,您无法轻松使用函数

    例如,您提到您对
    标签所提供的
    NGRAM
    感兴趣。使用dataframe1(df1),您可以通过一个简单的groupby和count函数轻松获得所需内容,而对于dataframe2(df2),您需要先分解列表列,然后才能使用它们:

    df1.groupby(['LABEL','NGRAM']).count().unstack(-1).fillna(0)
    
    df2.explode(column='NGRAM').groupby(['LABEL','NGRAM']).count().unstack(-1).fillna(0)
    
    两者都给了你同样的东西:

    此外,许多本机Pandas函数(例如我最喜欢的
    value\u counts
    )无法直接在列表上工作,因此几乎总是需要
    explode

  • 对于长数据,计算时间比列表数据要短(一般来说,因为我们不需要先分解列)
  • 假设您决定将您的
    NGRAM
    资本化,您将分别执行以下操作,您可以看到执行df2需要更长的时间:

    df1['NGRAM'] = df1['NGRAM'].str.capitalize()
    # 1000 loops, best of 5: 1.49 ms per loop
    
    df2['NGRAM'] = df2['NGRAM'].explode().str.capitalize().groupby(level=0).apply(list)
    # 1000 loops, best of 5: 246 µs per loop
    

    如果内存是一个问题,您可能需要考虑直接使用每个标签的ngram计数(在上面的图像中的数据结构,而不是将它们存储为DF1或DF2)或使用NUMPY数组(这稍微降低了熊猫的开销)同时单独保存一个NGRAM字典文件。

    @jezrael我不知道您是否能看到这一点,但先生,这不是一个重复的问题。链接的帖子解释了如何分解数据帧。我想问的是哪种结构更好,为什么。完全不同。很抱歉,重新开放。顺便说一句,我的意见是第二个,因为。但这可能取决于实际数据。这实际上取决于在这一步之后你需要对它做什么,你如何访问数据等等。在我看来,第二个选项将适合大多数情况。好的,第二个选择,如果它坏了,我将选择第一个。至少现在我知道第二个是理想的。谢谢你的回答!另一方面,您如何看待“超长、逗号分隔字符串”与“超长数据帧”?因为我的数据在一个包(如列表)中包含了大量NGRAM,如果我遵循DF2的结构,必然会有一个更大的数据帧。我喜欢你用标签计数制作一个超清晰的数据帧,实际上,这正是我最终想要得到的。但是,因为原始文本数据分散在很多文本文件中,需要许多NLP预处理步骤,所以我仍然要我必须首先处理这个结构问题。就我个人而言,我更喜欢使用存储为.txt文件的超长逗号分隔字符串,读取并处理每一行单独的文本文件,然后再将它们附加到数据框中。(熊猫数据框只是让事情更容易探索,但可能不是最有效的内存)您可以浏览
    collections.Counter
    ,这是Python的一种专门内置类型,用于存储项目计数,因此适合于n-grams存储。
    df1['NGRAM'] = df1['NGRAM'].str.capitalize()
    # 1000 loops, best of 5: 1.49 ms per loop
    
    df2['NGRAM'] = df2['NGRAM'].explode().str.capitalize().groupby(level=0).apply(list)
    # 1000 loops, best of 5: 246 µs per loop