【问题标题】:Extract info from each row of a dataframe without a loop从数据帧的每一行中提取信息而无需循环
【发布时间】:2021-07-24 16:49:29
【问题描述】:

我有一个大数据框(约 500,000 行)。处理每一行都会给我一个 Counter 对象(一个包含对象计数的字典)。我想要的输出是一个新的数据框,其中列标题是正在计算的对象(字典中的键)。我正在遍历行,但是它需要很长时间。我知道在 Pandas 中应该避免循环,有什么建议吗?

out_df = pd.DataFrame()
for row in input_df['text']:
    tokens = nltk.word_tokenize(row)
    pos = nltk.pos_tag(tokens)
    count = Counter(elem[1] for elem in pos)
    out_df = out_df.append(count, ignore_index=True)

作为指示,Counter(elem[1] for elem in pos) 看起来像 Counter({'NN':8, 'VBZ': 2, 'DT':3, 'IN': 4})

【问题讨论】:

    标签: pandas dataframe loops append nltk


    【解决方案1】:

    我认为可能必须使用矢量化解决方案:“遍历 pandas 对象通常很慢。在许多情况下,不需要手动迭代行并且可以避免(使用)矢量化解决方案:许多操作可以使用内置方法或 NumPy 函数执行(布尔)索引。" 来自https://towardsdatascience.com/you-dont-always-have-to-loop-through-rows-in-pandas-22a970b347ac

    【讨论】:

    • 我找不到向量化处理每一行的函数的方法——这可能是最有效的方法。
    【解决方案2】:

    我认为在数据帧上使用附加功能非常低效(每次都必须为整个数据帧重新分配内存)。

    DataFrames 用于分析数据和轻松添加列,而不是行。

    所以我认为更好的方法是首先创建列表(列表为mutable),然后将其转换为数据框。

    我对 nltk 不熟悉,所以我无法实际测试它,但以下几行应该可以工作:

    out_data = []
    for row in input_df['text']:
        tokens = nltk.word_tokenize(row)
        pos = nltk.pos_tag(tokens)
        count = Counter(elem[1] for elem in pos)
        out_data.append(count)
    out_df = pd.DataFrame(out_data)
    

    您可能需要添加以下内容以删除任何 NaN 并将最终计数转换为整数:

    out_df = out_df.fillna(0).astype(int)
    

    然后删除列表以释放内存:

    del out_data
    

    【讨论】:

    • 谢谢。它在大约 15 分钟内完成了这项工作
    • 优秀。如果您需要更快地完成它,那么下一步可能是并行处理解决方案。我认为使用Dask 很容易做到这一点。见this answer我写的一个文件处理问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-23
    • 2021-09-16
    相关资源
    最近更新 更多