pyspark, spark: как выбрать последнюю строку, а также Как получить доступ к фрейму данных pyspark по индексу

из фрейма данных pyspark sql, например

name age city
abc   20  A
def   30  B

Как получить последнюю строку.(Как на ДФ.limit (1) я могу получить первую строку фрейма данных в новый фрейм данных).

и как я могу получить доступ к таблице данных строк по индексу.как ряд нет. 12 или 200 .

в панд я могу сделать

df.tail(1) # for last row
df.ix[rowno or index] # by index
df.loc[] or by df.iloc[]

мне просто интересно, как получить доступ к PySpark dataframe такими способами или альтернативными способами.

спасибо

4 ответов


как получить последнюю строку.

длинный и уродливый способ, который предполагает, что все столбцы oderable:

from pyspark.sql.functions import (
    col, max as max_, struct, monotonically_increasing_id
)

last_row = (df
    .withColumn("_id", monotonically_increasing_id())
    .select(max(struct("_id", *df.columns))
    .alias("tmp")).select(col("tmp.*"))
    .drop("_id"))

если не все столбцы можно заказать, вы можете попробовать:

with_id = df.withColumn("_id", monotonically_increasing_id())
i = with_id.select(max_("_id")).first()[0]

with_id.where(col("_id") == i).drop("_id")

Примечание. Есть и доступен по индексу. вы можете добавить индексы, используя zipWithIndex и фильтр позже. Просто имейте в виду это O (N) операции.


как получить последнюю строку.

если у вас есть столбец, который вы можете использовать для заказа dataframe, например "index" , то одним из простых способов получить последнюю запись является использование SQL: 1) заказать таблицу по убыванию и 2) Возьмите 1-е значение из этого порядка

df.createOrReplaceTempView("table_df")
query_latest_rec = """SELECT * FROM table_df ORDER BY index DESC limit 1"""
latest_rec = self.sqlContext.sql(query_latest_rec)
latest_rec.show()

и как я могу получить доступ к таблице данных строк по индексу.как ряд нет. 12 или 200 .

аналогичным образом вы можете сделать запись в любой строке

row_number = 12
df.createOrReplaceTempView("table_df")
query_latest_rec = """SELECT * FROM (select * from table_df ORDER BY index ASC limit {0}) ord_lim ORDER BY index DESC limit 1"""
latest_rec = self.sqlContext.sql(query_latest_rec.format(row_number))
latest_rec.show()

если вы нет столбца" index", который вы можете создать с помощью

from pyspark.sql.functions import monotonically_increasing_id

df = df.withColumn("index", monotonically_increasing_id())

from pyspark.sql import functions as F

expr = [F.last(col).alias(col) for col in df.columns]

df.groupBy().agg(*expr)

просто совет: похоже, у вас все еще есть мышление кого-то, кто работает с пандами или R. Spark-это другая парадигма в том, как мы работаем с данными. Вы больше не получаете доступ к данным внутри отдельных ячеек, теперь вы работаете с целыми кусками. Если вы продолжаете собирать вещи и делать действия, как вы только что сделали, вы теряете всю концепцию параллелизма, которую дает spark. Взгляните на концепцию преобразований против действий в Spark.


используйте следующее, Чтобы получить столбец индекса, содержащий монотонно увеличивающийся, уникальный,и последовательные целые числа, то есть не как monotonically_increasing_id() работа. Индексы будут возрастать в том же порядке, что и colName вашего фрейма данных.

import pyspark.sql.functions as F
from pyspark.sql.window import Window as W

window = W.orderBy('colName').rowsBetween(W.unboundedPreceding, W.currentRow)

df = df\
 .withColumn('int', F.lit(1))\
 .withColumn('index', F.sum('int').over(window))\
 .drop('int')\

используйте следующий код, чтобы посмотреть на хвост, или last rownums таблицы данных.

rownums = 10
df.where(F.col('index')>df.count()-rownums).show()

используйте следующий код, чтобы посмотреть строки из start_row to end_row в Фрейм данных.

start_row = 20
end_row = start_row + 10
df.where((F.col('index')>start_row) & (F.col('index')<end_row)).show()

zipWithIndex() - это метод RDD, который возвращает монотонно увеличивающиеся, уникальные и последовательные целые числа, но, похоже, намного медленнее реализовать таким образом, чтобы вы могли вернуться к исходному фрейму данных, измененному столбцом id.