You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将含多类型数据的Pandas DataFrame转换为向量DataFrame?

问题描述

我有一个超过1000行的Pandas DataFrame,包含数值、对象、字符串和布尔值类型的数据。我想把DataFrame的每个单元格转换成向量,之后基于这些向量比较每行的相似性。

示例数据

Col 0,Col 1,Col 2,Col 3,Col 4,Col 5,Col 6,Col 7,Col 8,Col 9,Col 10
12,65e1e35b7fe333,harry Joe,1,FALSE,swe,1,142.158.0.2,10.10.0.2,text1,0
13,65e1e35b7fe599,allen,1,FALSE,swe,1,142.158.0.20,10.10.0.20,text2,0
14,65e1e35b7fe165,carter,1,FALSE,swe,1,142.158.0.21,10.10.0.21,text3,0

期望结果

希望得到每个单元格对应向量的DataFrame(示例用VectX表示向量):

Col 0,Col 1,Col 2,Col 3,Col 4,Col 5,Col 6,Col 7,Col 8,Col 9,Col 10
Vect1,Vect2,Vect3,Vect4,Vect5,Vect6,Vect7,Vect8,Vect9,Vect10,Vect11
Vect12,Vect13,Vect14,Vect4,Vect5,Vect6,Vect7,Vect15,Vect16,Vect17,Vect11
Vect18,Vect19,Vect20,Vect4,Vect5,Vect6,Vect7,Vect21,Vect22,Vect23,Vect11

尝试的代码及报错

我尝试用Scikit-learn的TfidfVectorizer实现,但报错了:

import pandas as pd 
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer

df = mydata

vectorizer = TfidfVectorizer()

# 转换数据为特征向量
X = vectorizer.fit_transform(df)
X = pd.DataFrame(_X.todense(), index=df.index, columns=vectorizer.vocabulary_)
X.head()

# 标签
y = df['label']

报错信息:

TypeError                                 Traceback (most recent call last)
Cell In[11], line 14
     11 vectorizer = TfidfVectorizer()
     13 # Transform the text data to feature vectors
---> 14 X = vectorizer.fit_transform(df)
     16 X = pd.DataFrame(_X.todense(), index=df.index, columns=vectorizer.vocabulary_)
     17 X.head()

File /anaconda/envs/xxx_py38/lib/python3.9/site-packages/sklearn/feature_extraction/text.py:2079, in TfidfVectorizer.fit_transform(self, raw_documents, y)
   2072 self._check_params()
   2073 self._tfidf = TfidfTransformer(
   2074     norm=self.norm,
   2075     use_idf=self.use_idf,
   2076     smooth_idf=self.smooth_idf,
   2077     sublinear_tf=self.sublinear_tf,
   2078 )
-> 2079 X = super().fit_transform(raw_documents)
   2080 self._tfidf.fit(X)
   2081 # X is already a transformed view of raw_documents so
   2082 # we set copy to False

File /anaconda/envs/xxx_py38/lib/python3.9/site-packages/sklearn/feature_extraction/text.py:1338, in CountVectorizer.fit_transform(self, raw_documents, y)
   1330             warnings.warn(
   1331                 "Upper case characters found in"
   1332                 " vocabulary while 'lowercase'"
   1333                 " is True. These entries will not"
   1334                 " be matched with any documents"
   1335             )
   1336             break
-> 1338 vocabulary, X = self._count_vocab(raw_documents, self.fixed_vocabulary_)
   1340 if self.binary:
   1341     X.data.fill(1)

File /anaconda/envs/xxx_py38/lib/python3.9/site-packages/sklearn/feature_extraction/text.py:1207, in CountVectorizer._count_vocab(self, raw_documents, fixed_vocab)
   1205 values = _make_int_array()
   1206 indptr.append(0)
-> 1207 for doc in raw_documents:
   1208     feature_counter = {}
   1209     for feature in analyze(doc):

TypeError: 'Data' object is not iterable
解决方案

报错原因

你直接把整个DataFrame传给TfidfVectorizer.fit_transform(),但这个方法只接受文本序列(比如字符串列表、单列文本Series),无法处理多列混合类型的DataFrame,因此抛出了'Data' object is not iterable的错误。

实现步骤

要实现每个单元格转向量并计算行相似性,需针对不同类型的列分别处理,再合并所有列的向量表示,最终得到每行的完整向量用于相似性计算:

  • 区分列类型:将DataFrame的列分为数值型(含布尔值)、字符串/对象型两类。
  • 分别向量化:数值/布尔列可直接保留数值或标准化;字符串/对象列用TF-IDF或词频统计转向量,结构化字符串(如IP)可拆分后转数值。
  • 合并向量:将各列的向量结果拼接,得到每行的完整特征向量。
  • 计算相似性:用余弦相似度或成对距离计算行之间的相似性。

示例代码

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.preprocessing import StandardScaler
from sklearn.metrics.pairwise import cosine_similarity

# 加载示例数据
data = """Col 0,Col 1,Col 2,Col 3,Col 4,Col 5,Col 6,Col 7,Col 8,Col 9,Col 10
12,65e1e35b7fe333,harry Joe,1,FALSE,swe,1,142.158.0.2,10.10.0.2,text1,0
13,65e1e35b7fe599,allen,1,FALSE,swe,1,142.158.0.20,10.10.0.20,text2,0
14,65e1e35b7fe165,carter,1,FALSE,swe,1,142.158.0.21,10.10.0.21,text3,0"""
df = pd.read_csv(pd.io.common.StringIO(data))

# 1. 处理数值/布尔列
numeric_cols = df.select_dtypes(include=['int64', 'float64', 'bool']).columns
scaler = StandardScaler()
numeric_vecs = scaler.fit_transform(df[numeric_cols])
numeric_df = pd.DataFrame(numeric_vecs, columns=[f"{col}_vec" for col in numeric_cols], index=df.index)

# 2. 处理字符串/对象列
text_cols = df.select_dtypes(include=['object']).columns
text_vec_list = []

for col in text_cols:
    vectorizer = TfidfVectorizer()
    col_vecs = vectorizer.fit_transform(df[col].astype(str))
    col_df = pd.DataFrame(col_vecs.todense(), 
                          columns=[f"{col}_vec_{word}" for word in vectorizer.get_feature_names_out()],
                          index=df.index)
    text_vec_list.append(col_df)

text_df = pd.concat(text_vec_list, axis=1)

# 3. 合并所有向量,得到每行完整特征向量
full_vec_df = pd.concat([numeric_df, text_df], axis=1)

# 4. 计算行余弦相似性
similarity_matrix = cosine_similarity(full_vec_df)
similarity_df = pd.DataFrame(similarity_matrix, index=df.index, columns=df.index)

print("每行完整特征向量:")
print(full_vec_df.head())
print("\n行相似性矩阵:")
print(similarity_df)

单元格单独存向量的实现

如果希望每个单元格单独存储向量(而非合并成大向量),可参考以下代码:

vec_df = df.copy()

# 处理文本列,每个单元格存TF-IDF向量
text_cols = df.select_dtypes(include=['object']).columns
for col in text_cols:
    vectorizer = TfidfVectorizer()
    vecs = vectorizer.fit_transform(df[col].astype(str))
    vec_df[col] = [row.toarray().flatten() for row in vecs]

# 处理数值/布尔列,转为单元素向量
numeric_cols = df.select_dtypes(include=['int64', 'float64', 'bool']).columns
for col in numeric_cols:
    vec_df[col] = df[col].apply(lambda x: [x])

print("每个单元格为向量的DataFrame:")
print(vec_df)

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 22:45:02