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

Spark Dataframe区分名称重复的列

尤博达
2023-03-14

正如我在Spark Dataframe中所知,对于多个列,可以使用以下Dataframe snapshot中所示的相同名称:

[
Row(a=107831, f=SparseVector(5, {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}), a=107831, f=SparseVector(5, {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0})),
Row(a=107831, f=SparseVector(5, {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}), a=125231, f=SparseVector(5, {0: 0.0, 1: 0.0, 2: 0.0047, 3: 0.0, 4: 0.0043})),
Row(a=107831, f=SparseVector(5, {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}), a=145831, f=SparseVector(5, {0: 0.0, 1: 0.2356, 2: 0.0036, 3: 0.0, 4: 0.4132})),
Row(a=107831, f=SparseVector(5, {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}), a=147031, f=SparseVector(5, {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0})),
Row(a=107831, f=SparseVector(5, {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}), a=149231, f=SparseVector(5, {0: 0.0, 1: 0.0032, 2: 0.2451, 3: 0.0, 4: 0.0042}))
]

上面的结果是通过将数据帧连接到自身创建的,您可以看到有4列,其中包含两个af

问题是,当我尝试使用a列进行更多计算时,我找不到选择a的方法,我尝试了df[0]df。选择('a'),两者都在下面返回了我的错误消息:

AnalysisException: Reference 'a' is ambiguous, could be: a#1333L, a#1335L.

无论如何,在Spark API中,我可以再次区分列和重复的名称吗?或者可以通过某种方式让我更改列名?

共有3个答案

曾枫
2023-03-14

有一种比为要连接的所有列编写别名更简单的方法,方法是:

df1.join(df2,['a'])

如果要联接的键在两个表中相同,则可以使用此方法。

看见https://kb.databricks.com/data/join-two-dataframes-duplicated-columns.html

淳于思淼
2023-03-14

我建议您更改加入的列名。

df1.select(col("a") as "df1_a", col("f") as "df1_f")
   .join(df2.select(col("a") as "df2_a", col("f") as "df2_f"), col("df1_a" === col("df2_a"))

生成的DataFrame将具有模式

(df1_a, df1_f, df2_a, df2_f)
朱典
2023-03-14

让我们从一些数据开始:

from pyspark.mllib.linalg import SparseVector
from pyspark.sql import Row

df1 = sqlContext.createDataFrame([
    Row(a=107831, f=SparseVector(
        5, {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0})),
    Row(a=125231, f=SparseVector(
        5, {0: 0.0, 1: 0.0, 2: 0.0047, 3: 0.0, 4: 0.0043})),
])

df2 = sqlContext.createDataFrame([
    Row(a=107831, f=SparseVector(
        5, {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0})),
    Row(a=107831, f=SparseVector(
        5, {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0})),
])

有几种方法可以解决这个问题。首先,可以使用父列明确地引用子表列:

df1.join(df2, df1['a'] == df2['a']).select(df1['f']).show(2)

##  +--------------------+
##  |                   f|
##  +--------------------+
##  |(5,[0,1,2,3,4],[0...|
##  |(5,[0,1,2,3,4],[0...|
##  +--------------------+

还可以使用表别名:

from pyspark.sql.functions import col

df1_a = df1.alias("df1_a")
df2_a = df2.alias("df2_a")

df1_a.join(df2_a, col('df1_a.a') == col('df2_a.a')).select('df1_a.f').show(2)

##  +--------------------+
##  |                   f|
##  +--------------------+
##  |(5,[0,1,2,3,4],[0...|
##  |(5,[0,1,2,3,4],[0...|
##  +--------------------+

最后,您可以通过编程方式重命名列:

df1_r = df1.select(*(col(x).alias(x + '_df1') for x in df1.columns))
df2_r = df2.select(*(col(x).alias(x + '_df2') for x in df2.columns))

df1_r.join(df2_r, col('a_df1') == col('a_df2')).select(col('f_df1')).show(2)

## +--------------------+
## |               f_df1|
## +--------------------+
## |(5,[0,1,2,3,4],[0...|
## |(5,[0,1,2,3,4],[0...|
## +--------------------+
 类似资料:
  • 我有一个原型项目,它的外观如下所示(有两个模块,和): 并且,当我使用工件id为“infra”的原型生成一个项目时,它应该生成如下结构: 不起作用的是,在父pom.xml中,我包含了以下模块: 这些模块条目不会被重命名为类似于(在生成时): 这就是我想要的。 知道怎么做吗,谢谢。 更新我在这里按要求添加元数据xml文件,但我不想修改archetype-metadata.xml文件。因为我想使用cr

  • 问题内容: 在两个具有相同列名的表上创建VIEW时,如何避免MySQL中的dup列名错误,如下所示 问题答案: 使用别名作为列名

  • 我有一个列名称为空的dataframe: 我如何删除空列名而不考虑位置?

  • 问题内容: 请考虑一个数组,例如: 是否有一个软件包可以进行分区以获得: 我可以看到如何通过for循环执行此操作,但如果存在的话,将不胜感激。 问题答案: 如果使用Underscore.js,则可以使用和实现

  • 嗨,有没有一种方法,我可以重命名的包名称使用这种格式 而不是仅仅 我尝试使用我想要的包名称,但它一直得到 或com+最后一个字后的最后一个“。 我这样做的原因是,我有一个需要一个包名,而我在该库中设置的包名是固定的,我不能更改它 对不起,我的英语不好

  • 问题内容: 我在另一个列名称为的团队的Postgres中有一个db表说。现在,我试图使用PG指令在此列名上查询该表。 它只是返回 错误:列“ first_Name”不存在 不知道我是在做傻事还是对我遗失的问题有解决方法? 问题答案: 所有未加双引号的 标识符 (包括列名)在PostgreSQL中被折叠为小写。用双引号创建的列名并因此保留了大写字母(和/或其他语法违规),必须在余下的时间将双引号引起