Как создать среднее распределение вложенной группы по данным в пандах? - PullRequest
0 голосов
/ 13 октября 2018

У меня есть фрейм данных, df1, я пытаюсь извлечь и усреднить распределения из:

   ID  site  timestamp  tracking_value
0  03  AMF 2018-01-01          1.0
1  08  AMF 2018-01-01          1.0
2  09  AMF 2018-01-01          1.0
3  14  ARR 2018-01-01          0.0
4  16  ARR 2018-01-01          0.0
5  21  AZM 2018-01-01          0.0
6  22  BII 2018-01-01          0.0
7  23  ARR 2018-01-01          0.0
8  26  AZM 2018-01-01          1.0
9  27  AMF 2018-01-01          1.0
                 ...
                 ...

Для каждой группы идентификаторов, для каждого сайта для этой группы идентификаторов я хочу получить распределение длинпоследовательных значений отслеживания.Затем я хочу усреднить эти распределения сайта для идентификатора, чтобы получить распределение отрезков времени, в течение которого tracking_value не было пропуском (0.0).

У меня это работает без второй группы по (группа по сайту), только для одного ID:

import more_itertools as mit
import seaborn as sns
id = '03'
# Get the tracking_value data for ID 03
data = df1[df1['ID'] == id]['tracking_value']
# Get the "run length" for each value in data
distribution_of_run_lengths = list(mit.run_length.encode(data))
# Keep the distribution of run lengths for only the 0.0 values
distribution_of_run_lengths_for_zero = [x[1] for x in disn if x[0] == 0.0]
# Plot the counts of run_lengths for each run_length value
sns.countplot(distribution_of_run_lengths_for_zero )

, что хорошо только для одного ID.График показывает количество раз (yaxis) у нас были длины отсева (xaxis) для идентификатора 03: Dropout lengths for ID 03

Однако мне нужно расширить это, как упомянуто выше, и начать сгруппировка по идентификатору, а затем по сайту, но я застрял на том, куда идти дальше:

data = df1.groupby(['ID','site'])['tracking_value']

Любые предложения о дальнейших действиях будут полезны.Спасибо.

1 Ответ

0 голосов
/ 13 октября 2018

Следующее должно делать то, что вы ищете.Настройка:

dates = np.repeat(pd.date_range('2018-01-01', '2018-01-31'), 4)
np.random.seed(100)
test_df = pd.DataFrame({
    'date': dates,
    'site': ['A', 'A', 'B', 'B']*(dates.shape[0]//4),
    'id': [1, 2, 1, 2]*(dates.shape[0]//4),
    'tracking_val': np.random.choice([0, 1], p=[0.4, 0.6], size=dates.shape)
})

Теперь выполните (много) groupby агрегаций, необходимых для получения желаемого:

run_length_dict = {} # place to hold results
for name, group in test_df.groupby(['site', 'id']):
    # Number all consecutive runs of 1 or 0
    runs = group['tracking_val'].ne(group['tracking_val'].shift()) \
                                .cumsum() \
                                .rename(columns={'tracking_val': 'run_number'})
    # Group each run by its number *and* the tracking value, then find the length of that run
    run_lengths = runs.groupby([runs, group['tracking_val']]).agg('size')
    # One final groupby (this time, on the tracking_val/level=1) to get the count of lengths
    # and push it into the dict with the name of the original group -  ("site", "id") tuple
    run_length_dict[name]  = run_lengths.groupby(level=1).value_counts()

Результат:

{('A', 1): tracking_val   
 0             1    2
               2    1
               3    1
               4    1
               5    1
 1             1    3
               2    3
               6    1
 dtype: int64, ('A', 2): tracking_val   
 0             1    5
               2    2
               3    1
               4    1
 1             1    6
               2    1
               3    1
               4    1
 dtype: int64, ('B', 1): tracking_val   
 0             1    6
               2    2
 1             2    4
               1    2
               4    2
               3    1
 dtype: int64, ('B', 2): tracking_val   
 0             1    5
               2    2
               3    2
 1             1    5
               2    2
               3    1
               4    1
 dtype: int64}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...