从数据帧的每一行中提取信息而无需循环
Posted
技术标签:
【中文标题】从数据帧的每一行中提取信息而无需循环【英文标题】: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)
【问题讨论】:
【参考方案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我写的一个文件处理问题。以上是关于从数据帧的每一行中提取信息而无需循环的主要内容,如果未能解决你的问题,请参考以下文章
芹菜任务设置与视频帧的内存缓存作为python中的循环缓冲区策略