当前位置: 首页 > 知识库问答 >
问题:

带虚拟变量的Pypark矩阵

沈高峻
2023-03-14

有两列:

ID  Text
1    a
2    b
3    c

我怎样才能用如下虚拟变量创建矩阵:

ID a b c
1  1 0 0
2  0 1 0
3  0 0 1

使用pyspark库及其功能?

共有3个答案

郭胤
2023-03-14

如果虚拟变量用于建模,则可以使用OneHotEncoder/OneHotEncoderRestimator(取决于pyspark的版本)。

Spark MLlib指南中给出了一个示例。

请注意,如果您需要删除一个列来防止线性依赖(就像回归一样),您应该使用dropLast=True

李光华
2023-03-14

另一种解决方案是使用Spark的pivot方法,该方法自Spark 1.6.0以来一直存在。

示例:

from pyspark.sql import functions as F

df = sqlContext.createDataFrame([
    (1, "a"),
    (2, "b"),
    (3, "c"),],
    ["ID", "Text"])    

pivoted = df.groupBy("ID").pivot("Text").agg(F.lit(1))
pivoted.show()
# +---+----+----+----+
# | ID|   a|   b|   c|
# +---+----+----+----+
# |  1|   1|null|null|
# |  3|null|null|   1|
# |  2|null|   1|null|
# +---+----+----+----+

要删除缺失的值,只需使用na方法:

pivoted.na.fill(0).show()
# +---+---+---+---+
# | ID|  a|  b|  c|
# +---+---+---+---+
# |  1|  1|  0|  0|
# |  3|  0|  0|  1|
# |  2|  0|  1|  0|
# +---+---+---+---+

数据透视比ksindi提出的解决方案更为普遍,因为它可以聚合数字。也就是说,ksindi提出的解决方案在这种特殊情况下更有效,因为它只需要对数据进行一次传递,如果您考虑传递以获得类别,则需要两次传递。对于透视,还可以将类别作为第二个位置参数添加到pivot,以提高效率。但是,groupBy调用已经会导致洗牌,这使得这种方法变得更慢。

注意:groupBy静默调用假定示例中的ID列包含唯一的值以获得所需的输出。如果示例数据帧看起来像:

df = sqlContext.createDataFrame([
    (1, "a"),
    (2, "b"),
    (3, "c"),
    (3, "a")],
    ["ID", "Text"]) 

这个解决方案的结果是

df.groupBy("ID").pivot("Text").agg(F.lit(1)).na.fill(0).show()
# +---+---+---+---+
# | ID|  a|  b|  c|
# +---+---+---+---+
# |  1|  1|  0|  0|
# |  3|  1|  0|  1|
# |  2|  0|  1|  0|
# +---+---+---+---+

而映射解决方案最终会成为

df.select("ID", *exprs).show()
# +---+---+---+---+
# | ID|  c|  b|  a|
# +---+---+---+---+
# |  1|  0|  0|  1|
# |  2|  0|  1|  0|
# |  3|  1|  0|  0|
# |  3|  0|  0|  1|
# +---+---+---+---+
田博远
2023-03-14
from pyspark.sql import functions as F

df = sqlContext.createDataFrame([
    (1, "a"),
    (2, "b"),
    (3, "c"),
], ["ID", "Text"])

categories = df.select("Text").distinct().rdd.flatMap(lambda x: x).collect()

exprs = [F.when(F.col("Text") == category, 1).otherwise(0).alias(category)
         for category in categories]

df.select("ID", *exprs).show()

输出

+---+---+---+---+
| ID|  a|  b|  c|
+---+---+---+---+
|  1|  1|  0|  0|
|  2|  0|  1|  0|
|  3|  0|  0|  1|
+---+---+---+---+
 类似资料:
  • 当一个方法返回多个值时,有些返回值有时候用不到,要是声明很多变量来一一接收,显然不太合适(不是不能)。Lua 提供了一个虚变量(dummy variable)的概念, 按照惯例以一个下划线(“_”)来命名,用它来表示丢弃不需要的数值,仅仅起到占位的作用。 看一段示例代码: -- string.find (s,p) 从string 变量s的开头向后匹配 string -- p,若匹配不成功,返回ni

  • 问题内容: 我正在尝试使用python中的pandas从类别变量中创建一系列虚拟变量。我遇到过该函数,但是每当我尝试调用该函数时,都会收到一个错误,提示您未定义名称。 创建虚拟变量的任何想法或其他方式将不胜感激。 编辑 :由于其他人似乎遇到了这种情况,因此熊猫中的函数现在可以正常工作了。这意味着以下应该起作用: 有关更多信息,请参见http://blog.yhathq.com/posts/logi

  • 我试图在python中使用pandas从一个分类变量创建一系列伪变量。我遇到了函数,但每当我尝试调用它时,都会收到一个错误,即名称未定义。 任何创建虚拟变量的想法或其他方法都将受到欢迎。 编辑:由于其他人似乎遇到了这种情况,熊猫中的功能现在运行得非常好。这意味着以下各项应起作用: 看见http://blog.yhathq.com/posts/logistic-regression-and-pyth

  • 在这些关于C 11/14标准的幻灯片中,在幻灯片15中,作者写道,“许多经典的编码规则不再适用于C 11中”。他提出了三个示例的列表,我同意三法则和内存管理。 然而,他的第二个例子是“具有虚拟成员的虚拟析构函数”(仅此而已)。这是什么意思?我知道必须将基类析构函数声明为虚拟,以便调用正确的析构函数,如果我们有类似的东西 这里很好地解释了:什么时候使用虚拟析构函数? 但是,如果您有虚拟成员,现在在C

  • 因此,我成功地设置了一个邮递员模拟服务器,并可以利用简单的GET,这些GET在api url中没有任何路径变量,但所有类似于<code>{{url}}/users/:urserId</code>或类似于<code>{{url}}/users/:userId/ffavorits</code>的GET都以<code>mockRequestNotFoundError</code>响应 只是想找出正确的方

  • 我的桌子是这样的: 在我使用get dummies之后,那么桌子是这样的: 我希望数字列只显示一次。有人能帮忙吗?谢谢!