def compute_tap_features(xtaps, ytaps, t, threshold=20): """ Elias Chaibub-Neto's tapping feature extraction methods. Arno translated Elias's R code to Python. Parameters ---------- xtaps : numpy array of integers x coordinates of touch screen where tapped ytaps : numpy array of integers y coordinates of touch screen where tapped t : numpy array of floats time points of taps threshold : integer x offset threshold for left/right press event (pixels) Return ------ T : class many features stored in TapFeatures class Examples -------- >>> import numpy as np >>> from mhealthx.extractors.tapping import compute_tap_features >>> xtaps = np.round(200 * np.random.random(100)) >>> ytaps = np.round(300 * np.random.random(100)) >>> t = np.linspace(1, 100, 100) / 5.0 >>> threshold = 20 >>> T = compute_tap_features(xtaps, ytaps, t, threshold) """ import numpy as np from mhealthx.extractors.tapping import compute_drift, \ compute_tap_intervals, compute_intertap_gap from mhealthx.extractors.tapping import TapFeatures as T from mhealthx.signals import signal_features if isinstance(xtaps, list): xtaps = np.array(xtaps) if isinstance(ytaps, list): ytaps = np.array(ytaps) if isinstance(t, list): t = np.array(t) # Intertap intervals: ipress, intervals = compute_tap_intervals(xtaps, t, threshold) # Filter data: t = t[ipress] xtaps = xtaps[ipress] ytaps = ytaps[ipress] # Delta between fastest and slowest intertap intervals: T.intertap_gap10, T.intertap_gap25, \ T.intertap_gap50 = compute_intertap_gap(intervals) # Left and right taps and drift: mean_x = np.mean(xtaps) iL = np.where(xtaps < mean_x) iR = np.where(xtaps >= mean_x) xL = xtaps[iL] yL = ytaps[iL] xR = xtaps[iR] yR = ytaps[iR] driftL = compute_drift(xL, yL) driftR = compute_drift(xR, yR) # Number of taps: T.num_taps = xtaps.size T.num_taps_left = xL.size T.num_taps_right = xR.size # Time: T.time_rng = t[-1] - t[0] # Intertap interval statistics: T.intertap_num, T.intertap_min, T.intertap_max, T.intertap_rng, \ T.intertap_avg, T.intertap_std, T.intertap_med, T.intertap_mad, \ T.intertap_kurt, T.intertap_skew, T.intertap_cvar, T.intertap_lower25, \ T.intertap_upper25, T.intertap_inter50, T.intertap_rms, \ T.intertap_entropy, T.intertap_tk_energy = signal_features(intervals) # Tap statistics: T.xL_num, T.xL_min, T.xL_max, T.xL_rng, T.xL_avg, T.xL_std, \ T.xL_med, T.xL_mad, T.xL_kurt, T.xL_skew, T.xL_cvar, \ T.xL_lower25, T.xL_upper25, T.xL_inter50, T.xL_rms, \ T.xL_entropy, T.xL_tk_energy = signal_features(xL) T.xR_num, T.xR_min, T.xR_max, T.xR_rng, T.xR_avg, T.xR_std, \ T.xR_med, T.xR_mad, T.xR_kurt, T.xR_skew, T.xR_cvar, \ T.xR_lower25, T.xR_upper25, T.xR_inter50, T.xR_rms, \ T.xR_entropy, T.xR_tk_energy = signal_features(xR) # T.yL_num, T.yL_min, T.yL_max, T.yL_rng, T.yL_avg, T.yL_std, \ # T.yL_med, T.yL_mad, T.yL_kurt, T.yL_skew, T.yL_cvar, \ # T.yL_lower25, T.yL_upper25, T.yL_inter50, T.yL_rms, \ # T.yL_entropy, T.yL_tk_energy = signal_features(yL) # T.yR_num, T.yR_min, T.yR_max, T.yR_rng, T.yR_avg, T.yR_std, \ # T.yR_med, T.yR_mad, T.yR_kurt, T.yR_skew, T.yR_cvar, \ # T.yR_lower25, T.yR_upper25, T.yR_inter50, T.yR_rms, \ # T.yR_entropy, T.yR_tk_energy = signal_features(yR) # Drift statistics: T.driftL_num, T.driftL_min, T.driftL_max, T.driftL_rng, T.driftL_avg, \ T.driftL_std, T.driftL_med, T.driftL_mad, T.driftL_kurt, T.driftL_skew, \ T.driftL_cvar, T.driftL_lower25, T.driftL_upper25, T.driftL_inter50, \ T.driftL_rms, T.driftL_entropy, T.driftL_tk_energy = \ signal_features(driftL) T.driftR_num, T.driftR_min, T.driftR_max, T.driftR_rng, T.driftR_avg, \ T.driftR_std, T.driftR_med, T.driftR_mad, T.driftR_kurt, T.driftR_skew, \ T.driftR_cvar, T.driftR_lower25, T.driftR_upper25, T.driftR_inter50, \ T.driftR_rms, T.driftR_entropy, T.driftR_tk_energy = \ signal_features(driftR) return T
def run_signal_features(data, row, file_path, table_stem, save_rows=False): """ Extract various features from time series data. Parameters ---------- data : numpy array of floats time series data row : pandas Series row to prepend, unaltered, to feature row file_path : string path to accelerometer file (from row) table_stem : string prepend to output table file save_rows : Boolean save individual rows rather than write to a single feature table? Returns ------- feature_row : pandas Series row combining the original row with a row of signal feature values feature_table : string output table file (full path) Examples -------- >>> import pandas as pd >>> from mhealthx.xio import read_accel_json >>> from mhealthx.extract import run_signal_features >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/accel_walking_outbound.json.items-6dc4a144-55c3-4e6d-982c-19c7a701ca243282023468470322798.tmp' >>> start = 150 >>> device_motion = False >>> t, axyz, gxyz, uxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> ax, data, az = axyz >>> row = pd.Series({'a':[1], 'b':[2], 'c':[3]}) >>> file_path = '.' >>> table_stem = './walking' >>> save_rows = True >>> feature_row, feature_table = run_signal_features(data, row, file_path, table_stem, save_rows) """ import pandas as pd from mhealthx.signals import signal_features from mhealthx.extract import make_row_table # Extract different features from the data: num, min, max, rng, avg, std, med, mad, kurt, skew, cvar, lower25, \ upper25, inter50, rms, entropy, tk_energy = signal_features(data) # Create row of data: row_data = pd.DataFrame({'num': num, 'min': min, 'max': max, 'rng': rng, 'avg': avg, 'std': std, 'med': med, 'mad': mad, 'kurt': kurt, 'skew': skew, 'cvar': cvar, 'lower25': lower25, 'upper25': upper25, 'inter50': inter50, 'rms': rms, 'entropy': entropy, 'tk_energy': tk_energy}, index=[0]) # Write feature row to a table or append to a feature table: feature_row, feature_table = make_row_table(file_path, table_stem, save_rows, row, row_data, feature_row=None) return feature_row, feature_table