手动修改CSV的sentiment列后读取显示NaN的解决方法
解决CSV读取后english与sentiment列全为NaN的问题
问题根源拆解
你碰到的NaN问题主要是两个细节没处理好:
- 编码拼写错误:保存CSV时用的是
encoding="utf-16",但读取时写成了encoding="utf_16"(横杠和下划线搞混了),这会直接导致Pandas解析编码失败,整列数据变成NaN。 - 复杂对象的字符串存储坑:原代码把TextBlob的
Sentiment(polarity=xx, subjectivity=xx)对象直接转成字符串存进CSV,手动修改后这个格式很容易被破坏;加上googletrans的翻译对象转成字符串后自带特殊格式,读写时很容易出解析问题。
分步解决方案
1. 先修复最基础的编码问题
把读取代码里的编码参数改对,横杠不要写成下划线:
df = pd.read_csv('output_file.csv', encoding="utf-16")
这一步能解决大部分因编码不匹配导致的NaN问题。
2. 优化原代码,从根源避免格式冲突
与其事后手动修改奇怪格式的字符串,不如在生成CSV时就把数据拆成简单的数值列,这样不管是手动编辑还是后续读取都更顺畅:
import pandas as pd from googletrans import Translator from textblob import TextBlob # 读取原始评论数据 df = pd.read_csv('input_file.csv', encoding="utf-16") # 翻译评论并提取纯文本结果(避免存翻译对象) translator = Translator() def translate_text(text): try: # 直接取翻译后的文本,不是整个翻译对象 return translator.translate(text, src='id', dest='en').text except Exception as e: print(f"翻译失败: {e}") return None df['english'] = df['Comment'].apply(translate_text) # 把情感分析结果拆成单独的数值列 def calculate_sentiment(text): if pd.isna(text): return pd.Series([None, None]) try: sentiment = TextBlob(text).sentiment # 返回polarity和subjectivity两个数值 return pd.Series([sentiment.polarity, sentiment.subjectivity]) except Exception as e: print(f"情感分析失败: {e}") return pd.Series([None, None]) # 新增两列存储情感数值 df[['polarity', 'subjectivity']] = df['english'].apply(calculate_sentiment) # 保存处理后的数据 df.to_csv('output_file.csv', mode='w', index=False, encoding="utf-16")
这样生成的CSV里,polarity和subjectivity是纯数值列,手动修改时直接改数字就行,完全不会有解析问题。
3. 抢救已经手动修改过的旧CSV
如果已经改了原来的CSV,想把数据救回来,可以用下面的代码解析sentiment列的字符串格式:
df = pd.read_csv('output_file.csv', encoding="utf-16") # 解析Sentiment(...)格式的字符串 def parse_sentiment_str(sent_str): if pd.isna(sent_str): return pd.Series([None, None]) # 提取括号里的内容,拆分键值对 content = sent_str.strip('Sentiment()') polarity_str, subjectivity_str = content.split(', ') polarity = float(polarity_str.split('=')[1]) subjectivity = float(subjectivity_str.split('=')[1]) return pd.Series([polarity, subjectivity]) # 生成单独的情感数值列 df[['polarity', 'subjectivity']] = df['sentiment'].apply(parse_sentiment_str) # 可以删掉原来的sentiment列 df = df.drop('sentiment', axis=1)
小提醒
- CSV适合存纯文本、数值这种简单数据,别把复杂对象直接转字符串存进去,很容易踩坑
- 读写CSV时编码一定要完全一致,utf-16、utf-8这类编码的拼写要仔细检查
- 翻译和情感分析都可能遇到异常(比如空文本、网络问题),加上try-except能避免整列数据因为一条错误变成NaN
内容的提问来源于stack exchange,提问作者Fawwaz Zaini Ahmad
相关产品推荐
相关产品推荐

