Все превосходные ответы, представленные здесь, сосредоточены на специфических требованиях оригинального плаката и сосредоточены на решении 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
существуют в комбинации в списке, но не как отдельное слово. Тестирование на «гниль» потерпит неудачу, но если один из элементов списка будет «гнить в аду», это тоже не удастся. Если вы используете этот метод, будьте осторожны с вашими критериями поиска и имейте это в виду.
Насколько я знаю, это невозможно напрямую ни в 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|
## +---+----------+----------+------------------+
Далеко не красиво, но работает.