web-dev-qa-db-ja.com

PandasデータフレームをSparkデータフレームエラーに変換しています

Pandas DFをSparkに変換しようとしています。 DF head:

10000001,1,0,1,12:35,OK,10002,1,0,9,f,NA,24,24,0,3,9,0,0,1,1,0,0,4,543
10000001,2,0,1,12:36,OK,10002,1,0,9,f,NA,24,24,0,3,9,2,1,1,3,1,3,2,611
10000002,1,0,4,12:19,PA,10003,1,1,7,f,NA,74,74,0,2,15,2,0,2,3,1,2,2,691

コード:

dataset = pd.read_csv("data/AS/test_v2.csv")
sc = SparkContext(conf=conf)
sqlCtx = SQLContext(sc)
sdf = sqlCtx.createDataFrame(dataset)

そして、エラーが発生しました:

TypeError: Can not merge type <class 'pyspark.sql.types.StringType'> and <class 'pyspark.sql.types.DoubleType'>
28

pandasデータフレーム列がsparkが推測するタイプに適していることを確認する必要があります。 pandasデータフレームに次のようなリストがある場合:

pd.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5062 entries, 0 to 5061
Data columns (total 51 columns):
SomeCol                    5062 non-null object
Col2                       5062 non-null object

そして、あなたはそのエラーを試しています:

df[['SomeCol', 'Col2']] = df[['SomeCol', 'Col2']].astype(str)

ここで、.astype(str)が実際にそれらの列に必要なタイプであることを確認してください。基本的に、基礎となるJavaコードがpython内のオブジェクトから型を推測しようとすると、いくつかの観測を使用して推測を行います(推測がすべてのデータに適用されない場合) pandasからsparkに変換しようとしている列は失敗します。

24
madman2890

タイプ関連のエラーは、次のようにスキーマを課すによって回避できます。

:元のデータ(上記)でテキストファイルが作成され(test.csv)、仮想列名は挿入(「col1」、「col2」、...、「col25」)。

import pyspark
from pyspark.sql import SparkSession
import pandas as pd

spark = SparkSession.builder.appName('pandasToSparkDF').getOrCreate()

pdDF = pd.read_csv("test.csv")

pandasデータフレームの内容:

pdDF

col1    col2    col3    col4    col5    col6    col7    col8    col9    col10   ... col16   col17   col18   col19   col20   col21   col22   col23   col24   col25
0   10000001    1   0   1   12:35   OK  10002   1   0   9   ... 3   9   0   0   1   1   0   0   4   543
1   10000001    2   0   1   12:36   OK  10002   1   0   9   ... 3   9   2   1   1   3   1   3   2   611
2   10000002    1   0   4   12:19   PA  10003   1   1   7   ... 2   15  2   0   2   3   1   2   2   691

次に、スキーマを作成します。

from pyspark.sql.types import *

mySchema = StructType([ StructField("Col1", LongType(), True)\
                       ,StructField("Col2", IntegerType(), True)\
                       ,StructField("Col3", IntegerType(), True)\
                       ,StructField("Col4", IntegerType(), True)\
                       ,StructField("Col5", StringType(), True)\
                       ,StructField("Col6", StringType(), True)\
                       ,StructField("Col7", IntegerType(), True)\
                       ,StructField("Col8", IntegerType(), True)\
                       ,StructField("Col9", IntegerType(), True)\
                       ,StructField("Col10", IntegerType(), True)\
                       ,StructField("Col11", StringType(), True)\
                       ,StructField("Col12", StringType(), True)\
                       ,StructField("Col13", IntegerType(), True)\
                       ,StructField("Col14", IntegerType(), True)\
                       ,StructField("Col15", IntegerType(), True)\
                       ,StructField("Col16", IntegerType(), True)\
                       ,StructField("Col17", IntegerType(), True)\
                       ,StructField("Col18", IntegerType(), True)\
                       ,StructField("Col19", IntegerType(), True)\
                       ,StructField("Col20", IntegerType(), True)\
                       ,StructField("Col21", IntegerType(), True)\
                       ,StructField("Col22", IntegerType(), True)\
                       ,StructField("Col23", IntegerType(), True)\
                       ,StructField("Col24", IntegerType(), True)\
                       ,StructField("Col25", IntegerType(), True)])

True(null許容を意味します)

pysparkデータフレームを作成します。

df = spark.createDataFrame(pdDF,schema=mySchema)

pandasデータフレームがpysparkデータフレームになったことを確認します。

type(df)

出力:

pyspark.sql.dataframe.DataFrame

以下のケイトのコメントに対処するには-一般的な(文字列)スキーマを課すために、次のことができます:

df=spark.createDataFrame(pdDF.astype(str)) 
24
Grant Shannon

私はあなたのデータでこれを試しましたが、それは機能しています:

%pyspark
import pandas as pd
from pyspark.sql import SQLContext
print sc
df = pd.read_csv("test.csv")
print type(df)
print df
sqlCtx = SQLContext(sc)
sqlCtx.createDataFrame(df).show()
7
RoyaumeIX

このアルゴリズムを作成し、10個のpandasデータフレームで機能しました

from pyspark.sql.types import *

# Auxiliar functions
def equivalent_type(f):
    if f == 'datetime64[ns]': return DateType()
    Elif f == 'int64': return LongType()
    Elif f == 'int32': return IntegerType()
    Elif f == 'float64': return FloatType()
    else: return StringType()

def define_structure(string, format_type):
    try: typo = equivalent_type(format_type)
    except: typo = StringType()
    return StructField(string, typo)


# Given pandas dataframe, it will return a spark's dataframe.
def pandas_to_spark(pandas_df):
    columns = list(pandas_df.columns)
    types = list(pandas_df.dtypes)
    struct_list = []
    i = 0
    for column, typo in Zip(columns, types): 
      struct_list.append(define_structure(column, typo))
    p_schema = StructType(struct_list)
    return sqlContext.createDataFrame(pandas_df, p_schema)

これもこれで見ることができます Gist

これにより、spark_df = pandas_to_spark(pandas_df)を呼び出すだけです

5
Gonzalo Garcia

私の場合、pandasデータフレームにNULLが含まれていたため、同様のエラーメッセージを1回受け取りました。 pandasに変換する前に、これをsparkで試して処理することをお勧めします(これで私の問題は解決しました)。

0
heathensoul