首页 > 解决方案 > 连接大型 CSV 文件中单词的最有效方法:pandas 还是 Python 标准库?

问题描述

我正在尝试进行文本分析,并将我的数据收集到一个包含三列的 CSV 文档中。我正在尝试将第二列中的所有文本组合成一个字符串以执行一些单词分析(词云、频率等)。我已经使用 pandas 导入了 CSV 文件。在下面的代码中,data是一个DataFrame对象。

# Extract words from comment column in data
words = " "
for msg in data["comment"]:
     msg = str(msg).lower()
     words = words + msg + " "
print("Length of words is:", len(words))

使用word_cloud解析输出。

wordcloud = WordCloud(width = 3000, height = 2000, random_state=1, collocations=False, stopwords = stopwordsTerrier.union(stopwordsExtra)).generate(words)

CSV 文件

rating, comment, ID
5, It’s just soooo delicious but silly price and postage price, XXX1
5, Love this salad dressing... One my kids will estv😊, XXX2
...

该代码适用于 <240kb 等的较小文件,但我最近正在处理一个 50mb 的文件,这大大减慢了脚本(179,697 行) - 我不确定它是否会完成计算。我确信这是瓶颈,因为我在 Jupyter 笔记本中运行脚本,这是我正在执行的单元格中的唯一代码。

我的问题是:有没有更有效的方法来做到这一点?

标签: pythonpandascsvlarge-dataword-cloud

解决方案


Pandas 解决方案(比标准库快 2.5 倍)

Pandas 系列可以转换为字符串:pandas.Series.str.cat

data = pd.read_csv(file_path)
words = data["comment"].str.cat(sep=' ').lower()

Python标准库解决方案(较慢)

import csv

comment_list = []
with open(file_path, newline='') as csv_file:
    reader = csv.DictReader(csv_file)
    for row in reader:
        comment_list.append(row["comment"])
words = " ".join(comment_list).lower()

性能测试

使用标准库与使用标准库读取 CSVpandas.read_csv

使用pandas.read_csv()速度至少比 Python 标准库包快 2.5 倍csv

创建一个测试 CSV 文件:test_data.csv

import random

reviews = [
    "Love this salad dressing... One my kids will estv😊",
    "It’s just soooo delicious but silly price and postage price",
    "The sitcome was entertaining but still a waste of time",
    "If only I had ten stomaches to enjoy everything the buffet had to offer"
]

with open("test_data.csv", "w") as file:
    file.write("random_number,comment,index\n")
    for i in range(10000):
        file.write(f"{random.randint(0, 9)},{random.choice(reviews)},{i}\n")

读取 CSV 文件 100 次

import csv
import pandas as pd
import timeit

def read_csv_stnd(file_path: str) -> str:
    comment_list = []
    with open(file_path, newline='') as csv_file:
        reader = csv.DictReader(csv_file)
        for row in reader:
            comment_list.append(row["comment"])
    return " ".join(comment_list).lower()

def read_csv_pandas(file_path: str) -> str:
    data = pd.read_csv(file_path)
    return data["comment"].str.cat(sep=' ').lower()

data_file = "test_data.csv"
print(f"Time to run read_csv_stnd 100 times: {timeit.timeit(lambda: read_csv_stnd(data_file), number=100)}")
print(f"Time to run read_csv_pandas 100 times: {timeit.timeit(lambda: read_csv_pandas(data_file), number=100)}")

读取CSV文件的结果:

Time to run read_csv_stnd 100 times: 2.349453884999093
Time to run read_csv_pandas 100 times: 0.9676197949993366

标准库lower()对比pandas.Series.str.lower

使用标准库函数lower()大约比使用快 5 倍pandas.Series.str.lower

pandas.Series.str.lower

>>> import pandas as pd
>>> import timeit
>>> 
>>> s = pd.Series(['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'])
>>> timeit.timeit(lambda: s.str.lower().str.cat(sep=' '), number=10000)
1.9734079910012952

lower()

>>> timeit.timeit(lambda: s.str.cat(sep=' ').lower(), number=10000)
0.3571630870010267

推荐阅读