电子数字/获取pyspark中的假人

时间:2017-03-15 09:26:36

标签: pyspark pyspark-sql

我想在 PYSPARK 中创建一个获取Dataframe和参数列表(代码/分类功能)的函数,并返回带有其他虚拟列的数据框,例如列表中功能的类别 DF前后PFA: before and After data frame- Example

python中的代码如下所示:

enum = ['column1','column2']

for e in enum:
    print e
    temp = pd.get_dummies(data[e],drop_first=True,prefix=e)
    data = pd.concat([data,temp], axis=1)
    data.drop(e,axis=1,inplace=True)

data.to_csv('enum_data.csv')

5 个答案:

答案 0 :(得分:5)

首先,您需要收集TYPESCODE的不同值。然后使用withColumn选择添加包含每个值名称的列,或者使用select for each columns。 以下是使用select语句的示例代码: -

import pyspark.sql.functions as F
df = sqlContext.createDataFrame([
    (1, "A", "X1"),
    (2, "B", "X2"),
    (3, "B", "X3"),
    (1, "B", "X3"),
    (2, "C", "X2"),
    (3, "C", "X2"),
    (1, "C", "X1"),
    (1, "B", "X1"),
], ["ID", "TYPE", "CODE"])

types = df.select("TYPE").distinct().rdd.flatMap(lambda x: x).collect()
codes = df.select("CODE").distinct().rdd.flatMap(lambda x: x).collect()
types_expr = [F.when(F.col("TYPE") == ty, 1).otherwise(0).alias("e_TYPE_" + ty) for ty in types]
codes_expr = [F.when(F.col("CODE") == code, 1).otherwise(0).alias("e_CODE_" + code) for code in codes]
df = df.select("ID", "TYPE", "CODE", *types_expr+codes_expr)
df.show()

输出

+---+----+----+--------+--------+--------+---------+---------+---------+
| ID|TYPE|CODE|e_TYPE_A|e_TYPE_B|e_TYPE_C|e_CODE_X1|e_CODE_X2|e_CODE_X3|
+---+----+----+--------+--------+--------+---------+---------+---------+
|  1|   A|  X1|       1|       0|       0|        1|        0|        0|
|  2|   B|  X2|       0|       1|       0|        0|        1|        0|
|  3|   B|  X3|       0|       1|       0|        0|        0|        1|
|  1|   B|  X3|       0|       1|       0|        0|        0|        1|
|  2|   C|  X2|       0|       0|       1|        0|        1|        0|
|  3|   C|  X2|       0|       0|       1|        0|        1|        0|
|  1|   C|  X1|       0|       0|       1|        1|        0|        0|
|  1|   B|  X1|       0|       1|       0|        1|        0|        0|
+---+----+----+--------+--------+--------+---------+---------+---------+

答案 1 :(得分:3)

Freek Wiemkeijer和Rakesh Kumar提供的解决方案是完全足够的,但是,因为我编写了它,我认为值得发布这个通用解决方案,因为它不需要对列名进行硬编码。

libsso.so.10

这给出了输出:

pivot_cols = ['TYPE','CODE']
keys = ['ID','TYPE','CODE']

before = sc.parallelize([(1,'A','X1'),
                         (2,'B','X2'),
                         (3,'B','X3'),
                         (1,'B','X3'),
                         (2,'C','X2'),
                         (3,'C','X2'),
                         (1,'C','X1'),
                         (1,'B','X1')]).toDF(['ID','TYPE','CODE'])                         

#Helper function to recursively join a list of dataframes
#Can be simplified if you only need two columns
def join_all(dfs,keys):
    if len(dfs) > 1:
        return dfs[0].join(join_all(dfs[1:],keys), on = keys, how = 'inner')
    else:
        return dfs[0]

dfs = []
combined = []
for pivot_col in pivot_cols:
    pivotDF = before.groupBy(keys).pivot(pivot_col).count()
    new_names = pivotDF.columns[:len(keys)] +  ["e_{0}_{1}".format(pivot_col, c) for c in pivotDF.columns[len(keys):]]        
    df = pivotDF.toDF(*new_names).fillna(0)    
    combined.append(df)

join_all(combined,keys).show()

答案 2 :(得分:1)

如果你想获得 PySpark 版本的 Pandas "pd.get_dummies" 函数,你可以使用以下函数:

import itertools

def spark_get_dummies(df):
    
    categories = []
    for i, values in enumerate(df.columns):
        categories.append(df.select(values).distinct().rdd.flatMap(lambda x: x).collect())
        
    expressions = []
    for i, values in enumerate(df.columns):
        expressions.append([F.when(F.col(values) == i, 1).otherwise(0).alias(str(values) + "_" + str(i)) for i in categories[i]])
    
    expressions_flat = list(itertools.chain.from_iterable(expressions))
    
    df_final = df.select(*expressions_flat)
    
    return df_final

可重现的例子是:

df = sqlContext.createDataFrame([
    ("A", "X1"),
    ("B", "X2"),
    ("B", "X3"),
    ("B", "X3"),
    ("C", "X2"),
    ("C", "X2"),
    ("C", "X1"),
    ("B", "X1"),
], ["TYPE", "CODE"])

dummies_df = spark_get_dummies(df)
dummies_df.show()

您将获得:

enter image description here

答案 3 :(得分:0)

第一步是从您的CSV文件中制作No 'Access-Control-Allow-Origin' header is present on the requested resource.

Get CSV to Spark dataframe;第一个答案给出了逐行的例子。

然后您可以添加列。假设您有一个名为DataFrame的{​​{1}}对象,其列为:[DataFramedfID]。

使用TYPECODE

修复其余货车
DataFrame.withColumn()

(这会增加前两列。你明白了。)

答案 4 :(得分:0)

我一直在寻找相同的解决方案,但却是scala,也许这会帮助某人:

val list = df.select("category").distinct().rdd.map(r => r(0)).collect()
val oneHotDf = list.foldLeft(df)((df, category) => finalDf.withColumn("category_" + category, when(col("category") === category, 1).otherwise(0)))