pandas 0.20.3处理pyspark.ml.vectors对象行为变化,如何恢复旧版行为?
解决pandas 0.20.3中PySpark向量列的输出行为问题
这个问题的根源在于pandas 0.20.3调整了apply方法处理可迭代对象的逻辑——pyspark.ml.linalg.Vectors.dense()返回的向量对象实现了迭代接口,新版本会自动将其拆分成多列,而0.20.0版本则是将整个向量作为单个元素保留在单列中。
要恢复0.20.0的输出行为,你可以用以下两种方法:
方法1:将向量包装为长度为1的列表后转成Series
通过把向量放到一个单元素列表里,告诉pandas不要拆分这个对象,而是作为一个整体放到列中:
import pandas as pd from pyspark.ml.linalg import Vectors df = pd.DataFrame({'A': [1,2,3,4], 'B': [1,2,3,4], 'C': [1,2,3,4], 'D': [1,2,3,4]}, index=[0, 1, 2, 3]) result = df.apply(lambda x: pd.Series([Vectors.dense([x["A"], x["B"]])]), axis=1) print(result)
输出会和0.20.0一致:
0 0 [1.0, 1.0] 1 [2.0, 2.0] 2 [3.0, 3.0] 3 [4.0, 4.0]
方法2:直接返回向量标量,再转成DataFrame
先通过apply返回单个向量对象,再用to_frame()将其转为单列DataFrame:
result = df.apply(lambda x: Vectors.dense([x["A"], x["B"]]), axis=1).to_frame(name=0) print(result)
这个方法的输出和上面完全相同,更简洁直接。
原理说明
在pandas 0.20.3中,当apply返回的对象是可迭代类型(比如PySpark的向量)时,框架会默认将其拆分为多列。而我们通过包装成单元素列表,或者直接返回标量再转成DataFrame,就能强制让pandas把整个向量作为单个元素保留在一列中,从而复刻旧版本的行为。
内容的提问来源于stack exchange,提问作者Don
相关产品推荐
相关产品推荐

