web-dev-qa-db-ja.com

TypeError:WithColumnを使用して 'Column'オブジェクトを呼び出すことはできません

関数get_distanceからのデータフレーム「df」に新しい列を追加したいと思います。

def get_distance(x, y):
    dfDistPerc = hiveContext.sql("select column3 as column3, \
                                  from tab \
                                  where column1 = '" + x + "' \
                                  and column2 = " + y + " \
                                  limit 1")

    result = dfDistPerc.select("column3").take(1)
    return result

df = df.withColumn(
    "distance",
    lit(get_distance(df["column1"], df["column2"]))
)

しかし、私はこれを得る:

TypeError: 'Column' object is not callable

XとyはColumnオブジェクトであり、クエリで使用するためにStringに変換する必要があるためだと思います。私は正しいですか?もしそうなら、どうすればこれを行うことができますか?

6
Bruno Canal
  • Columnオブジェクト/式を操作することを目的としていない限り、Columnオブジェクトに対してPython関数を直接使用することはできません。そのためにはudfが必要です。

    @udf
    def get_distance(x, y):
        ...
    
  • ただし、UDF(または一般的なマッパー)でSQLContextを使用することはできません。

  • ちょうどjoin

    tab = hiveContext.table("tab").groupBy("column1", "column2").agg(first("column3"))
    df.join(tab, ["column1", "column2"])
    
6
user9230621

Sparkは、使用している関数が通常の関数ではなくUDFであることを知っているはずです。

したがって、データフレームでUDFを使用する方法は2つあります。

方法-1:@udfアノテーションを使用

@udf
def get_distance(x, y):
    dfDistPerc = hiveContext.sql("select column3 as column3, \
                                  from tab \
                                  where column1 = '" + x + "' \
                                  and column2 = " + y + " \
                                  limit 1")

    result = dfDistPerc.select("column3").take(1)
    return result

df = df.withColumn(
    "distance",
    lit(get_distance(df["column1"], df["column2"]))
)

方法-2:pyspark.sql.functions.udfを使用してudfをレスタリングする

def get_distance(x, y):
    dfDistPerc = hiveContext.sql("select column3 as column3, \
                                  from tab \
                                  where column1 = '" + x + "' \
                                  and column2 = " + y + " \
                                  limit 1")

    result = dfDistPerc.select("column3").take(1)
    return result

calculate_distance_udf = udf(get_distance, IntegerType())

df = df.withColumn(
    "distance",
    lit(calculate_distance_udf(df["column1"], df["column2"]))
)
3
Ajit K'sagar