|
|
|
@ -14,7 +14,7 @@ FEATURES_CALLS = (
|
|
|
|
|
+ ["duration_total_" + call_types.get(1), "duration_total_" + call_types.get(2)]
|
|
|
|
|
+ ["duration_max_" + call_types.get(1), "duration_max_" + call_types.get(2)]
|
|
|
|
|
+ ["no_" + call_types.get(1) + "_ratio", "no_" + call_types.get(2) + "_ratio"]
|
|
|
|
|
+ ["no_contacts"]
|
|
|
|
|
+ ["no_contacts_calls"]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# FEATURES_CALLS =
|
|
|
|
@ -29,7 +29,7 @@ FEATURES_SMS = (
|
|
|
|
|
["no_sms_all"]
|
|
|
|
|
+ ["no_" + sms_type for sms_type in sms_types.values()]
|
|
|
|
|
+ ["no_" + sms_types.get(1) + "_ratio", "no_" + sms_types.get(2) + "_ratio"]
|
|
|
|
|
+ ["no_contacts"]
|
|
|
|
|
+ ["no_contacts_sms"]
|
|
|
|
|
)
|
|
|
|
|
# FEATURES_SMS =
|
|
|
|
|
# ["no_sms_all",
|
|
|
|
@ -156,6 +156,7 @@ def count_comms(comm_df: pd.DataFrame) -> pd.DataFrame:
|
|
|
|
|
* the number of communication contacts by type.
|
|
|
|
|
"""
|
|
|
|
|
if "call_type" in comm_df:
|
|
|
|
|
data_type = "calls"
|
|
|
|
|
comm_counts = (
|
|
|
|
|
comm_df.value_counts(subset=["participant_id", "call_type"])
|
|
|
|
|
.unstack()
|
|
|
|
@ -197,6 +198,7 @@ def count_comms(comm_df: pd.DataFrame) -> pd.DataFrame:
|
|
|
|
|
# If there were no missed calls, this exception is raised.
|
|
|
|
|
# But we are dropping the column anyway, so no need to deal with the exception.
|
|
|
|
|
elif "message_type" in comm_df:
|
|
|
|
|
data_type = "sms"
|
|
|
|
|
comm_counts = (
|
|
|
|
|
comm_df.value_counts(subset=["participant_id", "message_type"])
|
|
|
|
|
.unstack()
|
|
|
|
@ -216,7 +218,7 @@ def count_comms(comm_df: pd.DataFrame) -> pd.DataFrame:
|
|
|
|
|
enumerate_contacts(comm_df)
|
|
|
|
|
.groupby(["participant_id"])
|
|
|
|
|
.nunique()["contact_id"]
|
|
|
|
|
.rename("no_contacts")
|
|
|
|
|
.rename("no_contacts_" + data_type)
|
|
|
|
|
)
|
|
|
|
|
# Number of communication contacts
|
|
|
|
|
comm_features = comm_features.join(comm_contacts_counts)
|
|
|
|
@ -282,7 +284,7 @@ def calls_sms_features(df_calls: pd.DataFrame, df_sms: pd.DataFrame) -> pd.DataF
|
|
|
|
|
df_calls_sms: pd.DataFrame
|
|
|
|
|
The list of features relating calls and sms data for every participant.
|
|
|
|
|
These are:
|
|
|
|
|
* proportion_calls:
|
|
|
|
|
* proportion_calls_all:
|
|
|
|
|
proportion of calls in total number of communications
|
|
|
|
|
* proportion_calls_incoming:
|
|
|
|
|
proportion of incoming calls in total number of incoming/received communications
|
|
|
|
@ -295,9 +297,7 @@ def calls_sms_features(df_calls: pd.DataFrame, df_sms: pd.DataFrame) -> pd.DataF
|
|
|
|
|
"""
|
|
|
|
|
count_calls = count_comms(df_calls)
|
|
|
|
|
count_sms = count_comms(df_sms)
|
|
|
|
|
count_joined = count_calls.merge(
|
|
|
|
|
count_sms, on="participant_id", suffixes=("_calls", "_sms")
|
|
|
|
|
).assign( # Merge calls and sms features
|
|
|
|
|
count_joined = count_calls.join(count_sms).assign(
|
|
|
|
|
proportion_calls_all=(
|
|
|
|
|
lambda x: x.no_calls_all / (x.no_calls_all + x.no_sms_all)
|
|
|
|
|
),
|
|
|
|
@ -314,7 +314,5 @@ def calls_sms_features(df_calls: pd.DataFrame, df_sms: pd.DataFrame) -> pd.DataF
|
|
|
|
|
lambda x: x.no_contacts_calls / (x.no_contacts_calls + x.no_contacts_sms)
|
|
|
|
|
)
|
|
|
|
|
# Calculate new features and create additional columns
|
|
|
|
|
)[
|
|
|
|
|
FEATURES_CONTACT
|
|
|
|
|
] # Filter out only the relevant features
|
|
|
|
|
)
|
|
|
|
|
return count_joined
|
|
|
|
|