[python] Spark Dataframe은 중복 된 이름으로 열을 구별합니다.

따라서 Spark Dataframe에서 알 수 있듯이 여러 열의 경우 아래 데이터 프레임 스냅 샷에 표시된 것과 동일한 이름을 가질 수 있습니다.

[
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.select('a')모두 오류 mesaage 아래 나를 돌아 :

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

어쨌든 Spark API에 중복 된 이름과 열을 다시 구별 할 수있는 것이 있습니까? 아니면 열 이름을 변경할 수있는 방법이 있습니까?



답변

.NET Framework의 열 이름을 변경하는 것이 좋습니다 join.

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"))

결과 DataFrameschema

(df1_a, df1_f, df2_a, df2_f)


답변

몇 가지 데이터부터 시작하겠습니다.

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...|
## +--------------------+


답변

다음을 수행하여 결합하는 모든 열에 대한 별칭을 작성하는 것보다 더 간단한 방법이 있습니다.

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

이것은 조인하는 키가 두 테이블에서 동일 할 경우 작동합니다.

참조
https://kb.databricks.com/data/join-two-dataframes-duplicated-columns.html를


답변

def drop(col: Column)방법을 사용 하여 복제 된 열을 삭제할 수 있습니다 . 예를 들면 다음과 같습니다.

DataFrame:df1

+-------+-----+
| a     | f   |
+-------+-----+
|107831 | ... |
|107831 | ... |
+-------+-----+

DataFrame:df2

+-------+-----+
| a     | f   |
+-------+-----+
|107831 | ... |
|107831 | ... |
+-------+-----+

df1과 df2를 결합하면 DataFrame은 다음과 같습니다.

val newDf = df1.join(df2,df1("a")===df2("a"))

DataFrame:newDf

+-------+-----+-------+-----+
| a     | f   | a     | f   |
+-------+-----+-------+-----+
|107831 | ... |107831 | ... |
|107831 | ... |107831 | ... |
+-------+-----+-------+-----+

이제 def drop(col: Column)다음과 같이 메서드를 사용 하여 복제 된 열 ‘a’또는 ‘f’를 삭제할 수 있습니다 .

val newDfWithoutDuplicate = df1.join(df2,df1("a")===df2("a")).drop(df2("a")).drop(df2("f"))


답변

Spark API를 alias살펴본 후 먼저 원래 데이터 프레임에 대한 별칭을 생성하는 데 사용할 수 있음을 발견 한 다음 withColumnRenamed별칭의 모든 열의 이름을 수동으로 바꾸는 데 사용할 수 있습니다. 이렇게하면 join열 이름이 중복되지 않습니다.

자세한 내용은 아래 Spark Dataframe API를 참조하십시오 .

pyspark.sql.DataFrame.alias

pyspark.sql.DataFrame.withColumnRenamed

그러나 이것은 번거로운 해결 방법 일뿐이며 내 질문에 더 좋은 방법이 있는지 궁금합니다.


답변

이것이 PySpark 에서 동일한 열 이름에 있는 두 개의 Dataframe 결합하는 방법 입니다.

df = df1.join(df2, ['col1','col2','col3'])

당신이 할 경우 printSchema()이 후 당신은 중복 된 열이 제거 된 것을 볼 수 있습니다.


답변

조인하려는 DataFrame이 df1 및 df2이고 열 ‘a’에 조인한다고 가정하면 두 가지 방법이 있습니다.

방법 1

df1.join (df2, ‘a’, ‘left_outer’)

이것은 끔찍한 방법이며 적극 권장됩니다.

방법 2

df1.join (df2, df1.a == df2.a, ‘left_outer’). drop (df2.a)