Given a DataFrame:
import datetime
from pyspark.sql import Row
dataframe_rows = {
Row(id = "A", date = datetime.datetime(2015, 1, 18)),
Row(id = "A", date = datetime.datetime(2015, 2, 21)),
Row(id = "A", date = datetime.datetime(2015, 2, 22)),
Row(id = "A", date = datetime.datetime(2015, 6, 30)),
Row(id = "A", date = datetime.datetime(2017, 12, 31)),
Row(id = "B", date = datetime.datetime(2019, 1, 18)),
Row(id = "B", date = datetime.datetime(2019, 1, 21)),
Row(id = "B", date = datetime.datetime(2019, 2, 22)),
Row(id = "B", date = datetime.datetime(2019, 2, 28)),
Row(id = "B", date = datetime.datetime(2019, 12, 13)),
}
df_example = spark.createDataFrame(dataframe_rows).orderBy(["id", "date"], ascending=[1, 1])
So
df_example.show()
yields
+---+-------------------+
| id| date|
+---+-------------------+
| A|2015-01-18 00:00:00|
| A|2015-02-21 00:00:00|
| A|2015-02-22 00:00:00|
| A|2015-06-30 00:00:00|
| A|2017-12-31 00:00:00|
| B|2019-01-18 00:00:00|
| B|2019-01-21 00:00:00|
| B|2019-02-22 00:00:00|
| B|2019-02-28 00:00:00|
| B|2019-12-13 00:00:00|
+---+-------------------+
I want a function that will sample rows from this DataFrame such that a specified number of days are between each sample and such that the last date per id is the last date per id in the sampled DataFrame.
For example, using 14 days between each sample,
+---+-------------------+
| id| date|
+---+-------------------+
| A|2015-01-18 00:00:00|
| A|2015-02-22 00:00:00|
| A|2015-06-30 00:00:00|
| A|2017-12-31 00:00:00|
| B|2019-01-18 00:00:00|
| B|2019-02-28 00:00:00|
| B|2019-12-13 00:00:00|
+---+-------------------+
Note the last date for each id is the same as it was in the original DataFrame.
Edit: The solution below works with the original DataFrame that I provided but if I change it
from pyspark.sql import Row
dataframe_rows = {
Row(id = "A", date = datetime.datetime(2000, 11, 12)),
Row(id = "A", date = datetime.datetime(2000, 12, 13)),
Row(id = "A", date = datetime.datetime(2000, 12, 29)),
Row(id = "A", date = datetime.datetime(2000, 12, 30)),
Row(id = "A", date = datetime.datetime(2000, 12, 31)),
Row(id = "B", date = datetime.datetime(2002, 2, 18)),
Row(id = "B", date = datetime.datetime(2002, 2, 21)),
Row(id = "B", date = datetime.datetime(2002, 2, 27)),
Row(id = "B", date = datetime.datetime(2002, 2, 28)),
Row(id = "B", date = datetime.datetime(2002, 12, 13)),
}
df_example = spark.createDataFrame(dataframe_rows).orderBy(["id", "date"], ascending=[1, 1])
df_example.show()
yielding
+---+-------------------+
| id| date|
+---+-------------------+
| A|2000-11-12 00:00:00|
| A|2000-12-13 00:00:00|
| A|2000-12-29 00:00:00|
| A|2000-12-30 00:00:00|
| A|2000-12-31 00:00:00|
| B|2002-02-18 00:00:00|
| B|2002-02-21 00:00:00|
| B|2002-02-27 00:00:00|
| B|2002-02-28 00:00:00|
| B|2002-12-13 00:00:00|
+---+-------------------+
and apply the code I get
+---+----------+
| id| date|
+---+----------+
| A|2000-11-12|
| A|2000-12-13|
| A|2000-12-31|
| B|2002-02-27|
| B|2002-02-28|
| B|2002-12-13|
+---+----------+
I am not sure why both February dates survive. I expected to see
+---+----------+
| id| date|
+---+----------+
| A|2000-11-12|
| A|2000-12-13|
| A|2000-12-31|
| B|2002-02-28|
| B|2002-12-13|
+---+----------+
Any ideas?