2020-09-19 02:25:29 +02:00
|
|
|
import pandas as pd
|
|
|
|
import itertools
|
|
|
|
|
2020-12-03 00:41:03 +01:00
|
|
|
def getEpisodeDurationFeatures(screen_data, time_segment, episode, features, reference_hour_first_use):
|
2020-09-19 02:25:29 +02:00
|
|
|
screen_data_episode = screen_data[screen_data["episode"] == episode]
|
|
|
|
duration_helper = pd.DataFrame()
|
|
|
|
if "countepisode" in features:
|
2020-11-30 20:42:19 +01:00
|
|
|
duration_helper = pd.concat([duration_helper, screen_data_episode.groupby(["local_segment"])[["duration"]].count().rename(columns = {"duration": "countepisode" + episode})], axis = 1)
|
2020-09-19 02:25:29 +02:00
|
|
|
if "sumduration" in features:
|
2020-11-30 20:42:19 +01:00
|
|
|
duration_helper = pd.concat([duration_helper, screen_data_episode.groupby(["local_segment"])[["duration"]].sum().rename(columns = {"duration": "sumduration" + episode})], axis = 1)
|
2020-09-19 02:25:29 +02:00
|
|
|
if "maxduration" in features:
|
2020-11-30 20:42:19 +01:00
|
|
|
duration_helper = pd.concat([duration_helper, screen_data_episode.groupby(["local_segment"])[["duration"]].max().rename(columns = {"duration": "maxduration" + episode})], axis = 1)
|
2020-09-19 02:25:29 +02:00
|
|
|
if "minduration" in features:
|
2020-11-30 20:42:19 +01:00
|
|
|
duration_helper = pd.concat([duration_helper, screen_data_episode.groupby(["local_segment"])[["duration"]].min().rename(columns = {"duration": "minduration" + episode})], axis = 1)
|
2020-09-19 02:25:29 +02:00
|
|
|
if "avgduration" in features:
|
2020-11-30 20:42:19 +01:00
|
|
|
duration_helper = pd.concat([duration_helper, screen_data_episode.groupby(["local_segment"])[["duration"]].mean().rename(columns = {"duration":"avgduration" + episode})], axis = 1)
|
2020-09-19 02:25:29 +02:00
|
|
|
if "stdduration" in features:
|
2020-11-30 20:42:19 +01:00
|
|
|
duration_helper = pd.concat([duration_helper, screen_data_episode.groupby(["local_segment"])[["duration"]].std().rename(columns = {"duration":"stdduration" + episode})], axis = 1)
|
2020-09-19 02:25:29 +02:00
|
|
|
if "firstuseafter" + "{0:0=2d}".format(reference_hour_first_use) in features:
|
|
|
|
screen_data_episode_after_hour = screen_data_episode.copy()
|
|
|
|
screen_data_episode_after_hour["hour"] = pd.to_datetime(screen_data_episode["local_start_date_time"]).dt.hour
|
|
|
|
screen_data_episode_after_hour = screen_data_episode_after_hour[screen_data_episode_after_hour["hour"] >= reference_hour_first_use]
|
|
|
|
|
2020-11-30 20:42:19 +01:00
|
|
|
duration_helper = pd.concat([duration_helper, pd.DataFrame(screen_data_episode_after_hour.groupby(["local_segment"])[["local_start_date_time"]].min().local_start_date_time.apply(lambda x: (x.to_pydatetime().hour - reference_hour_first_use) * 60 + x.to_pydatetime().minute + (x.to_pydatetime().second / 60))).rename(columns = {"local_start_date_time":"firstuseafter" + "{0:0=2d}".format(reference_hour_first_use) + episode})], axis = 1)
|
2020-09-19 02:25:29 +02:00
|
|
|
return duration_helper
|
|
|
|
|
|
|
|
|
2020-12-03 00:41:03 +01:00
|
|
|
def rapids_features(sensor_data_files, time_segment, provider, filter_data_by_segment, *args, **kwargs):
|
2020-10-08 00:11:06 +02:00
|
|
|
|
|
|
|
screen_data = pd.read_csv(sensor_data_files["sensor_episodes"])
|
2020-09-19 02:25:29 +02:00
|
|
|
|
|
|
|
reference_hour_first_use = provider["REFERENCE_HOUR_FIRST_USE"]
|
|
|
|
requested_features_episodes = provider["FEATURES"]
|
|
|
|
requested_episode_types = provider["EPISODE_TYPES"]
|
|
|
|
ignore_episodes_shorter_than = provider["IGNORE_EPISODES_SHORTER_THAN"]
|
|
|
|
ignore_episodes_longer_than = provider["IGNORE_EPISODES_LONGER_THAN"]
|
|
|
|
|
|
|
|
# name of the features this function can compute
|
|
|
|
base_features_episodes = ["countepisode", "episodepersensedminutes", "sumduration", "maxduration", "minduration", "avgduration", "stdduration", "firstuseafter"]
|
|
|
|
base_episode_type = ["unlock"]
|
|
|
|
# the subset of requested features this function can compute
|
|
|
|
features_episodes_to_compute = list(set(requested_features_episodes) & set(base_features_episodes))
|
|
|
|
episode_type_to_compute = list(set(requested_episode_types) & set(base_episode_type))
|
|
|
|
|
|
|
|
features_episodes_to_compute = ["firstuseafter" + "{0:0=2d}".format(reference_hour_first_use) if feature_name == "firstuseafter" else feature_name for feature_name in features_episodes_to_compute]
|
|
|
|
features_to_compute = ["".join(feature) for feature in itertools.product(features_episodes_to_compute, episode_type_to_compute)]
|
|
|
|
|
2020-11-30 20:42:19 +01:00
|
|
|
screen_features = pd.DataFrame(columns=["local_segment"] + features_to_compute)
|
2020-09-19 02:25:29 +02:00
|
|
|
if not screen_data.empty:
|
|
|
|
|
2020-12-03 00:41:03 +01:00
|
|
|
screen_data = filter_data_by_segment(screen_data, time_segment)
|
2020-11-19 23:27:53 +01:00
|
|
|
|
2020-09-19 02:25:29 +02:00
|
|
|
if not screen_data.empty:
|
|
|
|
if ignore_episodes_shorter_than > 0:
|
2020-09-30 00:05:25 +02:00
|
|
|
screen_data = screen_data.query('@ignore_episodes_shorter_than <= duration')
|
2020-09-19 02:25:29 +02:00
|
|
|
if ignore_episodes_longer_than > 0:
|
2020-09-30 00:05:25 +02:00
|
|
|
screen_data = screen_data.query('duration <= @ignore_episodes_longer_than')
|
2020-09-19 02:25:29 +02:00
|
|
|
|
|
|
|
if not screen_data.empty:
|
|
|
|
screen_features = pd.DataFrame()
|
|
|
|
for episode in episode_type_to_compute:
|
2020-12-03 00:41:03 +01:00
|
|
|
screen_features = pd.concat([screen_features, getEpisodeDurationFeatures(screen_data, time_segment, episode, features_episodes_to_compute, reference_hour_first_use)], axis=1)
|
2020-09-19 02:25:29 +02:00
|
|
|
|
|
|
|
if not screen_features.empty:
|
2021-11-19 16:34:36 +01:00
|
|
|
screen_features.fillna(value={feature_name: 0 for feature_name in screen_features.columns if not feature_name.startswith(("stdduration", "firstuseafter"))}, inplace=True)
|
2020-09-19 02:25:29 +02:00
|
|
|
screen_features = screen_features.reset_index()
|
|
|
|
|
|
|
|
return screen_features
|
|
|
|
|