Apache Spark에서 Dataframe의 열 값을 List로 추출
데이터 프레임의 문자열 열을 목록으로 변환하고 싶습니다. Dataframe
API 에서 찾을 수있는 것은 RDD이므로 먼저 RDD로 다시 변환 한 다음 toArray
RDD에 기능을 적용 해 보았습니다 . 이 경우 길이와 SQL이 잘 작동합니다. 그러나 RDD에서 얻은 결과에는 이와 같은 모든 요소 주위에 대괄호가 있습니다 [A00001]
. 열을 목록으로 변환하는 적절한 방법이나 대괄호를 제거하는 방법이 있는지 궁금합니다.
모든 제안을 주시면 감사하겠습니다. 감사합니다!
단일 목록을 포함하는 컬렉션을 반환해야합니다.
dataFrame.select("YOUR_COLUMN_NAME").rdd.map(r => r(0)).collect()
매핑이 없으면 데이터베이스의 모든 열을 포함하는 Row 개체 만 가져옵니다.
이것은 아마도 모든 유형의 목록을 얻을 것임을 명심하십시오. 결과 유형을 지정하려면 r => r(0).asInstanceOf[YOUR_TYPE]
매핑에 .asInstanceOf [YOUR_TYPE]을 사용할 수 있습니다.
추신 자동 변환으로 인해 .rdd
부분을 건너 뛸 수 있습니다 .
Spark 2.x 및 Scala 2.11 사용
특정 열의 값을 List로 변환하는 세 가지 가능한 방법을 생각합니다.
모든 접근 방식에 대한 공통 코드 조각
import org.apache.spark.sql.SparkSession
val spark = SparkSession.builder.getOrCreate
import spark.implicits._ // for .toDf() method
val df = Seq(
("first", 2.0),
("test", 1.5),
("choose", 8.0)
).toDF("id", "val")
접근 방식 1
df.select("id").collect().map(_(0)).toList
// res9: List[Any] = List(one, two, three)
지금 무슨 일이 일어나는거야? Driver에 데이터를 수집 collect()
하고 각 레코드에서 요소 0을 선택합니다.
이것은 훌륭한 방법이 될 수 없습니다. 다음 접근 방식으로 개선합시다.
접근 방식 2
df.select("id").rdd.map(r => r(0)).collect.toList
//res10: List[Any] = List(one, two, three)
어떻게 더 낫습니까? 단일 드라이버가 아닌 작업자간에 맵 변환로드를 분산했습니다.
I의 노하우는 rdd.map(r => r(0))
없습니다 당신이 우아한 보인다 않습니다. 따라서 다음 접근 방식에서 해결하겠습니다.
접근 3
df.select("id").map(r => r.getString(0)).collect.toList
//res11: List[String] = List(one, two, three)
여기서는 DataFrame을 RDD로 변환하지 않습니다. 에서 봐 map
그것을 수락하지 않습니다 r => r(0)
(또는 _(0)
인해 DataFrame에서 인코더 문제 이전의 방식으로). 그래서 결국 사용 r => r.getString(0)
하고 Spark의 다음 버전에서 해결 될 것입니다.
결론
모든 옵션은 동일한 출력을 제공하지만 2와 3은 효과적이며 마지막으로 세 번째 옵션은 효과적이고 우아합니다 (내 생각에는).
2017/05/20부터 6 개월까지 사용할 수있는 Databricks 노트북 링크
나는 주어진 대답이 Scala에 대해 가정된다는 것을 알고 있으므로 PySpark 사용자가 궁금한 경우를 대비하여 Python 코드의 작은 스 니펫을 제공하고 있습니다. 구문은 주어진 대답과 유사하지만 목록을 제대로 표시하려면 실제로 매핑 함수에서 열 이름을 두 번 참조해야하며 select 문이 필요하지 않습니다.
즉 "Raw"라는 열을 포함하는 DataFrame
각 항목이 "Raw"의 행 값인 목록으로 결합 된 "Raw"의 각 행 값을 얻으려면 다음을 사용합니다.
MyDataFrame.rdd.map(lambda x: x.Raw).collect()
Scala 및 Spark 2+에서 다음을 시도하십시오 (열 이름이 "s"라고 가정). df.select('s).as[String].collect
sqlContext.sql(" select filename from tempTable").rdd.map(r => r(0)).collect.toList.foreach(out_streamfn.println) //remove brackets
완벽하게 작동합니다
'Development Tip' 카테고리의 다른 글
TSQL : 현지 시간을 UTC로 변환하는 방법은 무엇입니까? (0) | 2020.10.31 |
---|---|
Vim에서 Bash 스크립트를 강조하는 방법은 무엇입니까? (0) | 2020.10.31 |
Android Studio 3.4로 업그레이드 한 후 resources_ap 관련 오류 (0) | 2020.10.31 |
Rails has_many : Join Model의 추가 속성으로 찾기 (0) | 2020.10.31 |
참조 된 모든 어셈블리를 앱 도메인에 강제로로드하는 방법이 있습니까? (0) | 2020.10.31 |