데이터 프레임의 문자열 열을 목록으로 변환하고 싶습니다. 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은 효과적이며 마지막으로 세 번째 옵션은 효과적이고 우아합니다 (내 생각에는).
답변
나는 주어진 대답이 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
완벽하게 작동합니다
답변
from pyspark.sql.functions import col
df.select(col("column_name")).collect()
여기에 수집은 차례로 목록으로 변환하는 함수입니다. 방대한 데이터 세트의 목록을 사용하십시오. 성능이 저하됩니다. 데이터를 확인하는 것이 좋습니다.
답변
List<String> whatever_list = df.toJavaRDD().map(new Function<Row, String>() {
public String call(Row row) {
return row.getAs("column_name").toString();
}
}).collect();
logger.info(String.format("list is %s",whatever_list)); //verification
아무도 java (Real Programming Language)에 대한 해결책을 제시하지 않았기 때문에 나중에 감사 할 수 있습니다.