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
두 개의 a
및 f
.
문제는 a
열을 사용하여 더 많은 계산을 수행하려고 할 때 를 선택하는 방법을 찾을 수 없다는 것입니다. a
, 시도했습니다 df[0]
및 df.select('a')
, 둘 다 오류 메시지 아래에 저를 반환했습니다.
AnalysisException: Reference 'a' is ambiguous, could be: a#1333L, a#1335L.
어쨌든 Spark API에 중복 된 이름과 열을 다시 구분할 수있는 것이 있습니까? 아니면 열 이름을 변경할 수있는 방법이 있습니까?
열 이름을 변경하는 것이 좋습니다. join
df1.select('a as "df1_a", 'f as "df1_f")
.join(df2.select('a as "df2_a", 'f as "df2_f"), 'df1_a === 'df2_a)
결과 DataFrame
는schema
(df1_a, df1_f, df2_a, df2_f)
순수한 파이썬 솔루션이 필요한 경우 selectExpr()
대신 select()
SQL 스타일 이름 변경을 사용할 수 있습니다.
df1.selectExpr("a as df1_a", "f as df1_f")
.join(df2.selectExpr("a as df2_a", "f as df2_f"), ["a"])
몇 가지 데이터부터 시작하겠습니다.
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 = df1.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를
After digging into the Spark API, I found I can first use alias
to create an alias for the original dataframe, then I use withColumnRenamed
to manually rename every column on the alias, this will do the join
without causing the column name duplication.
More detail can be refer to below Spark Dataframe API:
pyspark.sql.DataFrame.withColumnRenamed
However, I think this is only a troublesome workaround, and wondering if there is any better way for my question.
You can use def drop(col: Column)
method to drop the duplicated column,for example:
DataFrame:df1
+-------+-----+
| a | f |
+-------+-----+
|107831 | ... |
|107831 | ... |
+-------+-----+
DataFrame:df2
+-------+-----+
| a | f |
+-------+-----+
|107831 | ... |
|107831 | ... |
+-------+-----+
when I join df1 with df2, the DataFrame will be like below:
val newDf = df1.join(df2,df1("a")===df2("a"))
DataFrame:newDf
+-------+-----+-------+-----+
| a | f | a | f |
+-------+-----+-------+-----+
|107831 | ... |107831 | ... |
|107831 | ... |107831 | ... |
+-------+-----+-------+-----+
Now, we can use def drop(col: Column)
method to drop the duplicated column 'a' or 'f', just like as follows:
val newDfWithoutDuplicate = df1.join(df2,df1("a")===df2("a")).drop(df2("a")).drop(df2("f"))
This is how we can join two Dataframes on same column names in PySpark.
df = df1.join(df2, ['col1','col2','col3'])
If you do printSchema()
after this then you can see that duplicate columns have been removed.
Suppose the DataFrames you want to join are df1 and df2, and you are joining them on column 'a', then you have 2 methods
Method 1
df1.join(df2,'a','left_outer')
This is an awsome method and it is highly recommended.
Method 2
df1.join(df2,df1.a == df2.a,'left_outer').drop(df2.a)
This might not be the best approach, but if you want to rename the duplicate columns(after join), you can do so using this tiny function.
def rename_duplicate_columns(dataframe):
columns = dataframe.columns
duplicate_column_indices = list(set([columns.index(col) for col in columns if columns.count(col) == 2]))
for index in duplicate_column_indices:
columns[index] = columns[index]+'2'
dataframe = dataframe.toDF(*columns)
return dataframe
If you have a more complicated use case than described in the answer of Glennie Helles Sindholt e.g. you have other/few non-join column names that are also same and want to distinguish them while selecting it's best to use aliasses, e.g:
df3 = df1.select("a", "b").alias("left")\
.join(df2.select("a", "b").alias("right"), ["a"])\
.select("left.a", "left.b", "right.b")
df3.columns
['a', 'b', 'b']
ReferenceURL : https://stackoverflow.com/questions/33778664/spark-dataframe-distinguish-columns-with-duplicated-name
'development' 카테고리의 다른 글
두 개의 Eloquent 컬렉션을 병합하는 방법은 무엇입니까? (0) | 2020.12.28 |
---|---|
상대 경로로 파일에 액세스하는 NodeJS (0) | 2020.12.28 |
헤더 파일에서 정적 const char *를 선언하는 방법은 무엇입니까? (0) | 2020.12.28 |
헤더 파일에서 정적 const char *를 선언하는 방법은 무엇입니까? (0) | 2020.12.28 |
C #의 확장 메서드에 해당하는 Scala? (0) | 2020.12.28 |