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.
스파크 API에서 중복된 이름과 열을 다시 구분할 수 있는 방법이 있습니까?아니면 칼럼 이름을 바꿀 수 있는 방법이 있을까요?
몇 가지 데이터부터 시작하겠습니다.
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...|
## +--------------------+
의 열 이름을 변경하는 것이 좋습니다.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"))
그 결과DataFrame
을 가질 것입니다schema
(df1_a, df1_f, df2_a, df2_f)
다음을 수행하여 가입 중인 모든 열에 대한 별칭을 작성하는 것보다 간단한 방법이 방법은 다음과 같습니다.
df1.join(df2,['a'])
이 기능은 가입 중인 키가 두 테이블에서 동일한 경우에 작동합니다.
https://kb.databricks.com/data/join-two-dataframes-duplicated-columns.html 을 참조하십시오.
이렇게 하면 PySpark에서 동일한 열 이름으로 두 개의 데이터 프레임을 결합할 수 있습니다.
df = df1.join(df2, ['col1','col2','col3'])
네가 한다면.printSchema()
그러면 중복된 열이 제거된 것을 볼 수 있습니다.
사용할 수 있습니다.def drop(col: Column)
중복된 열을 삭제하는 방법, 예:
DataFrame:df1
+-------+-----+
| a | f |
+-------+-----+
|107831 | ... |
|107831 | ... |
+-------+-----+
DataFrame:df2
+-------+-----+
| a | f |
+-------+-----+
|107831 | ... |
|107831 | ... |
+-------+-----+
df1을 df2로 가입시키면 데이터 프레임은 다음과 같습니다.
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"))
가입하려는 데이터 프레임이 df1 및 df2이고 열 'a'에 가입한다고 가정하면 두 가지 방법이 있습니다.
방법 1
df1.df(df2, 'a', 'left_df')
이것은 놀라운 방법이며 강력하게 추천합니다.
방법 2
df1.df(df2,df1.a == df2.a,'left_df').drop(df2.a)
Spark API를 파고든 후에 처음으로 사용할 수 있다는 것을 알게 되었습니다.alias
원래 데이터 프레임에 대한 별칭을 생성하려면 다음을 사용합니다.withColumnRenamed
별칭의 모든 열 이름을 수동으로 변경하려면 다음 작업을 수행합니다.join
열 이름 중복을 유발하지 않습니다.
자세한 내용은 아래 Spark Dataframe API를 참조하십시오.
하지만, 저는 이것이 단지 골치 아픈 해결책이라고 생각하고, 제 질문에 더 좋은 방법이 없을까 생각합니다.
두 표 모두에서 키 열만 같을 경우 다음 방법을 사용합니다(접근법 1).
left. join(right , 'key', 'inner')
아래가 아닌 (아래 2):
left. join(right , left.key == right.key, 'inner')
접근법 1의 장점:
- '키'는 최종 데이터 프레임에서 한 번만 표시됩니다.
- 구문을 사용하기 쉬운
접근법 1 사용의 단점:
- 키 열에 대한 도움말만 제공
- 왼쪽 조인의 경우 오른쪽 키 Null 카운트를 사용할 계획이면 작동하지 않는 시나리오입니다.이 경우 위에서 언급한 대로 키 중 하나의 이름을 변경해야 합니다.
이 방법이 최선의 방법은 아닐 수도 있지만, 중복된 열의 이름을 변경하려면(가입 후) 이 작은 함수를 사용하여 이름을 변경할 수 있습니다.
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
Glennie Helles Sindholt의 답변에 설명된 것보다 더 복잡한 사용 사례가 있는 경우(예: 다른/소수의 비조인 열 이름이 동일하며 별칭을 사용하는 것이 가장 좋습니다. 예:
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']
나에게 효과가 있었던 것
import databricks.koalas as ks
df1k = df1.to_koalas()
df2k = df2.to_koalas()
df3k = df1k.merge(df2k, on=['col1', 'col2'])
df3 = df3k.to_spark()
col1과 col2를 제외한 모든 열에는 df1에서 온 경우 "_x"가 추가되고 df2에서 온 경우 "_y"가 추가되어 정확히 제가 필요로 했던 것입니다.
Pyspark 3.2.1 +
32에서 Spark 3..1을 사용하여 .toDF
df.show()
+------+------+---------+
|number| word| word|
+------+------+---------+
| 1| apple| banana|
| 2|cherry| pear|
| 3| grape|pineapple|
+------+------+---------+
df = df.toDF(*[val + str(i) for i, val in enumerate(df.columns)])
df.show()
+-------+------+---------+
|number0| word1| word2|
+-------+------+---------+
| 1| apple| banana|
| 2|cherry| pear|
| 3| grape|pineapple|
+-------+------+---------+
언급URL : https://stackoverflow.com/questions/33778664/spark-dataframe-distinguish-columns-with-duplicated-name
'programing' 카테고리의 다른 글
WHERE를 사용할 수 있는데 왜 외부 키를 사용해야 합니까? (0) | 2023.07.23 |
---|---|
파이썬에서 다른 클래스 내에서 클래스를 정의하면 이점이 있습니까? (0) | 2023.07.23 |
데이터 프레임의 여러 데이터 그룹을 하나의 그림으로 표시하는 방법 (0) | 2023.07.23 |
MySQL에서 지연 함수 시뮬레이션 (0) | 2023.07.23 |
오라클 업데이트 문에서 테이블 이름 대신 하위 조회 사용 (0) | 2023.07.23 |