You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何解决Pandas DataFrame使用append方法后列顺序变更并将result列追加至原列末尾

保留原CSV列顺序并追加新列的解决方案

你的问题出在两个地方:一是每次循环都重新初始化KeyBERT模型,这会极大拖慢运行速度;二是空的DataFrame使用append添加Series时,Pandas会自动按列名字母顺序排序,导致原列顺序被打乱。

下面是修正后的代码,既保留原列顺序,又优化了性能:

import pandas as pd
from keybert import KeyBERT

# 1. 读取原始CSV,保留原列顺序
df_info = pd.read_csv(r'./old.csv', encoding='utf-8')

# 2. 只初始化一次KeyBERT模型(关键优化!不要放在循环里)
model = KeyBERT('distilbert-base-nli-mean-tokens')

# 3. 定义关键词提取函数,用apply批量处理,比循环iterrows高效
def get_keywords(doc):
    return model.extract_keywords(doc, keyphrase_ngram_range=(1, 1))

# 4. 在原DataFrame上直接添加result列,默认会追加到所有原列的最后
df_info['result'] = df_info['info'].apply(get_keywords)

# 5. 保存CSV,此时列顺序就是D, info, B, A, C, result
df_info.to_csv(r'./new.csv', index=False, mode='w', header=True, encoding='utf-8-sig')

为什么这个方法有效?

  • 直接在原df_info上添加新列时,Pandas会默认把新列放在所有现有列的末尾,完美符合你想要的原列顺序 + result的要求。
  • 将KeyBERT模型初始化放在循环外,避免了重复加载模型的巨大性能开销,运行速度会提升很多。
  • 使用apply批量处理比iterrows循环更高效,尤其是当你的CSV行数较多时。

如果你坚持要使用循环iterrows的方式(不推荐,效率较低),可以这样修改来保留列顺序:

import pandas as pd
from keybert import KeyBERT

df_info = pd.read_csv(r'./old.csv', encoding='utf-8')
# 提前定义目标列顺序:原列 + result
target_columns = df_info.columns.tolist() + ['result']
# 初始化带有指定列的空DataFrame
df_re = pd.DataFrame(columns=target_columns)
# 只初始化一次模型
model = KeyBERT('distilbert-base-nli-mean-tokens')

for index, row in df_info.iterrows():
    doc = row['info']
    a = model.extract_keywords(doc, keyphrase_ngram_range=(1, 1))
    row['result'] = a
    # 按指定列顺序将row转为DataFrame后追加
    df_re = pd.concat([df_re, pd.DataFrame([row], columns=target_columns)], ignore_index=True)

df_re.to_csv(r'./new.csv', index=False, mode='w', header=True, encoding='utf-8-sig')

这个方法通过提前指定df_re的列顺序,避免了append时自动排序的问题,但性能不如第一种方法,所以优先推荐第一种方案。

内容的提问来源于stack exchange,提问作者CR7

火山引擎 最新活动