scipyスパース行列をpyspark.sql.dataframe.DataFrameに変換する の方法について以前に質問し、提供された回答と この記事 を読んだ後、ある程度の進歩を遂げました=。最終的に、scipy.sparse.csc_matrixをpandasデータフレームに変換するための次のコードに到達しました:
df = pd.DataFrame(csc_mat.todense()).to_sparse(fill_value=0)
df.columns = header
次に、提案された構文を使用して、pandasデータフレームをsparkデータフレームに変換してみました:
spark_df = sqlContext.createDataFrame(df)
ただし、次のエラーが返されます。
ValueError: cannot create an RDD from type: <type 'list'>
ほぼ同じサイズの別のpandasデータフレームをsparkデータフレームに変換できたので、sqlContextとは何の関係もないと思います。問題。何か考えはありますか?
この質問が現在のバージョンのpySparkにまだ関連しているかどうかはわかりませんが、この質問を投稿してから数週間後に解決した解決策を次に示します。コードはかなり醜く、おそらく非効率的ですが、この質問に引き続き関心があるため、ここに投稿します。
from pyspark import SparkContext
from pyspark.sql import HiveContext
from pyspark import SparkConf
from py4j.protocol import Py4JJavaError
myConf = SparkConf(loadDefaults=True)
sc = SparkContext(conf=myConf)
hc = HiveContext(sc)
def chunks(lst, k):
"""Yield k chunks of close to equal size"""
n = len(lst) / k
for i in range(0, len(lst), n):
yield lst[i: i + n]
def reconstruct_rdd(lst, num_parts):
partitions = chunks(lst, num_parts)
for part in range(0, num_parts - 1):
print "Partition ", part, " started..."
partition = next(partitions) # partition is a list of lists
if part == 0:
prime_rdd = sc.parallelize(partition)
else:
second_rdd = sc.parallelize(partition)
prime_rdd = prime_rdd.union(second_rdd)
print "Partition ", part, " complete!"
return prime_rdd
def build_col_name_list(len_cols):
name_lst = []
for i in range(1, len_cols):
idx = "_" + str(i)
name_lst.append(idx)
return name_lst
def set_spark_df_header(header, sdf):
oldColumns = build_col_name_lst(len(sdf.columns))
newColumns = header
sdf = reduce(lambda sdf, idx: sdf.withColumnRenamed(oldColumns[idx], newColumns[idx]), xrange(len(oldColumns)), sdf)
return sdf
def convert_pdf_matrix_to_sdf(pdf, sdf_header, num_of_parts):
try:
sdf = hc.createDataFrame(pdf)
except ValueError:
lst = pdf.values.tolist() #Need to convert to list of list to parallelize
try:
rdd = sc.parallelize(lst)
except Py4JJavaError:
rdd = reconstruct_rdd(lst, num_of_parts)
sdf = hc.createDataFrame(rdd)
sdf = set_spark_df_header(sdf_header, sdf)
return sdf
to_sparse(fill_value=0)
は基本的に廃止されています。標準のバリアントを使用するだけです
sqlContext.createDataFrame(pd.DataFrame(csc_mat.todense()))
タイプに互換性がある限り、問題はありません。