| import pandas as pd
|
|
|
| def build_df(
|
| visits_df: pd.DataFrame,
|
| ads_activity_df: pd.DataFrame,
|
| surf_depth_df: pd.DataFrame,
|
| primary_device_df: pd.DataFrame,
|
| cloud_usage_df: pd.DataFrame,
|
| users_df: pd.DataFrame = pd.DataFrame(),
|
| ) -> pd.DataFrame:
|
|
|
| visits_df = visits_df.copy()
|
| ads_df = ads_activity_df.copy()
|
| surf_df = surf_depth_df.copy()
|
| device_df = primary_device_df.copy()
|
| cloud_df = cloud_usage_df.copy()
|
| users_df = users_df.copy()
|
| users_df_empty = not users_df.empty
|
|
|
|
|
| visits_df = visits_df.drop_duplicates(
|
| subset=["date", "daytime", "session_id", "user_id", "website_category"]
|
| )
|
| ads_df = ads_df.drop_duplicates(subset=["user_id"])
|
| if users_df_empty:
|
| users_df = users_df.drop_duplicates(subset=["user_id"])
|
|
|
|
|
| daytime_map = {
|
| "утро": "morning",
|
| "день": "day",
|
| "вечер": "evening",
|
| "ночь": "night",
|
| }
|
| visits_df["daytime"] = visits_df["daytime"].replace(daytime_map)
|
|
|
|
|
| visits_df["website_category"] = (
|
| visits_df["website_category"]
|
| .astype(str)
|
| .str.strip()
|
| .str.replace(" ", "_", regex=False)
|
| .str.lower()
|
| )
|
|
|
|
|
| visits_df["date"] = pd.to_datetime(visits_df["date"], errors="coerce").dt.date
|
|
|
|
|
|
|
| base_stats_df = visits_df.groupby("user_id").agg(
|
| total_sessions=("session_id", "nunique"),
|
| unique_days=("date", "nunique"),
|
| n_unique_categories=("website_category", "nunique")
|
| )
|
|
|
|
|
| base_stats_df["sessions_per_day"] = base_stats_df["total_sessions"] / base_stats_df[
|
| "unique_days"
|
| ].replace(0, 1)
|
|
|
|
|
| daytime_shares_df = pd.crosstab(
|
| visits_df["user_id"],
|
| visits_df["daytime"],
|
| normalize="index",
|
| )
|
|
|
|
|
| expected_daytimes = ["morning", "day", "evening", "night"]
|
| daytime_shares_df = daytime_shares_df.reindex(
|
| columns=expected_daytimes, fill_value=0.0
|
| )
|
| daytime_shares_df.columns = [
|
| f"daytime_{c}_share" for c in daytime_shares_df.columns
|
| ]
|
|
|
|
|
| base_stats_df["most_active_daytime"] = (
|
| daytime_shares_df.idxmax(axis=1)
|
| .str.replace("daytime_", "", regex=False)
|
| .str.replace("_share", "", regex=False)
|
| )
|
|
|
|
|
| webcat_shares_df = pd.crosstab(
|
| visits_df["user_id"],
|
| visits_df["website_category"],
|
| normalize="index",
|
| )
|
|
|
|
|
| webcat_cols = sorted(webcat_shares_df.columns)
|
| webcat_shares_df = webcat_shares_df.reindex(columns=webcat_cols, fill_value=0.0)
|
| webcat_shares_df.columns = [f"web_{c}_share" for c in webcat_shares_df.columns]
|
|
|
|
|
| base_stats_df["top_category_share"] = webcat_shares_df.max(axis=1)
|
|
|
|
|
| visits_features_df = pd.concat(
|
| [base_stats_df, daytime_shares_df, webcat_shares_df], axis=1
|
| ).reset_index()
|
|
|
|
|
| ads_activity_map = {
|
| "очень редко": "very_rarely",
|
| "редко": "rarely",
|
| "умеренно": "moderately",
|
| "часто": "often",
|
| "очень часто": "very_often",
|
| }
|
| ads_df["ads_activity"] = ads_df["ads_activity"].replace(ads_activity_map)
|
|
|
|
|
| surf_depth_map = {
|
| "поверхностно": "shallow",
|
| "средне": "medium",
|
| "глубоко": "deep",
|
| }
|
| surf_df["surf_depth"] = surf_df["surf_depth"].replace(surf_depth_map)
|
|
|
|
|
| primary_device_map = {
|
| "смартфон": "smartphone",
|
| "ПК": "pc",
|
| "ноутбук": "laptop",
|
| "планшет": "tablet",
|
| }
|
| device_df["primary_device"] = device_df["primary_device"].replace(
|
| primary_device_map
|
| )
|
|
|
|
|
| cloud_usage_map = {
|
| False: "not",
|
| True: "yes",
|
| }
|
| cloud_df["cloud_usage"] = cloud_df["cloud_usage"].replace(cloud_usage_map)
|
|
|
|
|
|
|
| if users_df_empty:
|
| features_df = users_df.merge(visits_features_df, on="user_id", how="left")
|
| features_df = features_df.merge(ads_df, on="user_id", how="left")
|
| else:
|
| features_df = ads_df.merge(visits_features_df, on="user_id", how="left")
|
|
|
| features_df = features_df.merge(surf_df, on="user_id", how="left")
|
| features_df = features_df.merge(device_df, on="user_id", how="left")
|
| features_df = features_df.merge(cloud_df, on="user_id", how="left")
|
|
|
| return features_df
|
|
|