Pyspark - разбить столбец и взять n элементов - PullRequest
1 голос
/ 13 марта 2019

Я хочу взять столбец и разбить строку, используя символ. Как обычно, я понимал, что метод split будет возвращать список, но при кодировании я обнаружил, что возвращающий объект имеет только методы getItem или getField со следующими описаниями из API:

@since(1.3)   
def getItem(self, key):
    """
    An expression that gets an item at position ``ordinal`` out of a list,
    or gets an item by key out of a dict.


@since(1.3)
def getField(self, name):
    """
    An expression that gets a field by name in a StructField.

Очевидно, что это не соответствует моим требованиям, например, для текста в столбце "A_B_C_D", который я хотел бы разделить между "A_B_C_" и "D" в двух разных столбцах.

Это код, который я использую

from pyspark.sql.functions import regexp_extract, col, split
df_test=spark.sql("SELECT * FROM db_test.table_test")
#Applying the transformations to the data

split_col=split(df_test['Full_text'],'_')
df_split=df_test.withColumn('Last_Item',split_col.getItem(3))

Найти пример:

from pyspark.sql import Row
from pyspark.sql.functions import regexp_extract, col, split
l = [("Item1_Item2_ItemN"),("FirstItem_SecondItem_LastItem"),("ThisShouldBeInTheFirstColumn_ThisShouldBeInTheLastColumn")]
rdd = sc.parallelize(l)
datax = rdd.map(lambda x: Row(fullString=x))
df = sqlContext.createDataFrame(datax)
split_col=split(df['fullString'],'_')
df=df.withColumn('LastItemOfSplit',split_col.getItem(2))

Результат:

fullString                                                LastItemOfSplit
Item1_Item2_ItemN                                            ItemN
FirstItem_SecondItem_LastItem                                LastItem
ThisShouldBeInTheFirstColumn_ThisShouldBeInTheLastColumn     null

Мой ожидаемый результат будет иметь всегда последний элемент

fullString                                                LastItemOfSplit
Item1_Item2_ItemN                                            ItemN
FirstItem_SecondItem_LastItem                                LastItem
ThisShouldBeInTheFirstColumn_ThisShouldBeInTheLastColumn  ThisShouldBeInTheLastColumn

Ответы [ 2 ]

2 голосов
/ 13 марта 2019

Вы можете использовать getItem(size - 1), чтобы получить последний элемент из массивов:

Пример :

df = spark.createDataFrame([[['A', 'B', 'C', 'D']], [['E', 'F']]], ['split'])
df.show()
+------------+
|       split|
+------------+
|[A, B, C, D]|
|      [E, F]|
+------------+

import pyspark.sql.functions as F
df.withColumn('lastItem', df.split.getItem(F.size(df.split) - 1)).show()
+------------+--------+
|       split|lastItem|
+------------+--------+
|[A, B, C, D]|       D|
|      [E, F]|       F|
+------------+--------+

Для вашего случая:

from pyspark.sql.functions import regexp_extract, col, split, size
df_test=spark.sql("SELECT * FROM db_test.table_test")
#Applying the transformations to the data

split_col=split(df_test['Full_text'],'_')
df_split=df_test.withColumn('Last_Item',split_col.getItem(size(split_col) - 1))
0 голосов
/ 13 марта 2019

Вы можете передать шаблон регулярного выражения в split.

Для вашего примера будет работать следующее:

from pyspark.sql.functions split

split_col=split(df['fullString'], r"_(?=.+$)")
df = df.withColumn('LastItemOfSplit', split_col.getItem(1))
df.show(truncate=False)
#+--------------------------------------------------------+---------------------------+
#|fullString                                              |LastItemOfSplit            |
#+--------------------------------------------------------+---------------------------+
#|Item1_Item2_ItemN                                       |Item2                      |
#|FirstItem_SecondItem_LastItem                           |SecondItem                 |
#|ThisShouldBeInTheFirstColumn_ThisShouldBeInTheLastColumn|ThisShouldBeInTheLastColumn|
#+--------------------------------------------------------+---------------------------+

Шаблон означает следующее:

  • _ буквальное подчеркивание
  • (?=.+$) позитивный прогноз на все (.) до конца строки $

Это разделит строку на последнее подчеркивание.Затем вызовите .getItem(1), чтобы получить элемент с индексом 1 в результирующем списке.

...