Использование Window.rowsBetween в искровой scala [дубликат]

Все превосходные ответы, представленные здесь, сосредоточены на специфических требованиях оригинального плаката и сосредоточены на решении if 1 in {x,y,z}, выдвинутом Мартином Питером. То, что они игнорируют, является более широким следствием вопроса: как проверить одну переменную на несколько значений? Предоставленное решение не будет работать для частичных ударов, если использовать строки, например: Проверьте, есть ли строка «Wild» в нескольких значениях

>>> x="Wild things"
>>> y="throttle it back"
>>> z="in the beginning"
>>> if "Wild" in {x,y,z}: print (True)
... 

или

>>> x="Wild things"
>>> y="throttle it back"
>>> z="in the beginning"
>>> if "Wild" in [x,y,z]: print (True)
... 

для этого сценария проще всего преобразовать в строку

>>> [x,y,z]
['Wild things', 'throttle it back', 'in the beginning']
>>> {x,y,z}
{'in the beginning', 'throttle it back', 'Wild things'}
>>> 

>>> if "Wild" in str([x,y,z]): print (True)
... 
True
>>> if "Wild" in str({x,y,z}): print (True)
... 
True

. Однако следует отметить, что, как упоминалось @codeforester, эти граничные слова теряются с помощью этого метода, как в:

>>> x=['Wild things', 'throttle it back', 'in the beginning']
>>> if "rot" in str(x): print(True)
... 
True

3 буквы rot существуют в комбинации в списке, но не как отдельное слово. Тестирование на «гниль» потерпит неудачу, но если один из элементов списка будет «гнить в аду», это тоже не удастся. Если вы используете этот метод, будьте осторожны с вашими критериями поиска и имейте это в виду.

11
задан zero323 20 October 2015 в 00:59
поделиться

1 ответ

Насколько я знаю, это невозможно напрямую ни в Spark, ни в Hive. Оба требуют, чтобы предложение ORDER BY, используемое с RANGE, было числовым. Самое близкое, что я нашел, это преобразование в временную метку и работу в секундах. Предполагая, что столбец start содержит date тип:

from pyspark.sql import Row

row = Row("id", "start", "some_value")
df = sc.parallelize([
    row(1, "2015-01-01", 20.0),
    row(1, "2015-01-06", 10.0),
    row(1, "2015-01-07", 25.0),
    row(1, "2015-01-12", 30.0),
    row(2, "2015-01-01", 5.0),
    row(2, "2015-01-03", 30.0),
    row(2, "2015-02-01", 20.0)
]).toDF().withColumn("start", col("start").cast("date"))

Маленькое определение помощника и окна:

from pyspark.sql.window import Window
from pyspark.sql.functions import mean, col


# Hive timestamp is interpreted as UNIX timestamp in seconds*
days = lambda i: i * 86400 

Наконец запрос:

w = (Window()
   .partitionBy(col("id"))
   .orderBy(col("start").cast("timestamp").cast("long"))
   .rangeBetween(-days(7), 0))

df.select(col("*"), mean("some_value").over(w).alias("mean")).show()

## +---+----------+----------+------------------+
## | id|     start|some_value|              mean|
## +---+----------+----------+------------------+
## |  1|2015-01-01|      20.0|              20.0|
## |  1|2015-01-06|      10.0|              15.0|
## |  1|2015-01-07|      25.0|18.333333333333332|
## |  1|2015-01-12|      30.0|21.666666666666668|
## |  2|2015-01-01|       5.0|               5.0|
## |  2|2015-01-03|      30.0|              17.5|
## |  2|2015-02-01|      20.0|              20.0|
## +---+----------+----------+------------------+

Далеко не красиво, но работает.


* Руководство по языку улья, Типы

27
ответ дан zero323 24 August 2018 в 04:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: