Объедините кадры данных Pandas с данными интервалов (сверху вниз) и создайте новый df с наименьшими возможными интервалами - PullRequest
0 голосов
/ 04 января 2019

У меня есть два кадра данных с данными и атрибутами интервала глубины

df1

ID Top Bottom Value_1  
A     0   2       CC  
A     2   8       DD  
A     10  15      EE  
B     3   20      FF  

df2   

ID Top Bottom Value_2  
A     0   4       XX  
A     4   6       YY  
A     8   20      ZZ  
B     0   10      NN  
B     10  50      MM  

Я хочу объединить их, используя панд, в новый кадр данных, который имеет наименьшие возможные интервалы для каждого идентификатораи создайте столбец с объединенным значением (на основе наименьшего интервала).Как показано ниже

df_combine

ID Top Bottom Value_1 Value_2 Value_combined  
A     0   2       CC    XX        CC  
A     2   4       DD    XX        XX  
A     4   6       DD    YY        YY  
A     6   8       DD    -         DD   
A     8   10      -     ZZ        ZZ  
A     10  15      EE    ZZ        EE  
A     15  20      -     ZZ        ZZ  
B     0   3       -     NN        NN  
B     3   10      FF    NN        NN  
B     10  20      FF    MM        FF  
B     20  50      -     MM        MM  

1 Ответ

0 голосов
/ 04 января 2019

Я предлагаю следующие шаги:

import pandas as pd
import numpy as np

1 / Разбить каждый фрейм данных (каждая строка повторяется столько раз, сколько снизу вверх)

def explode_df(df, value):
    df['interval'] = df['Bottom'] - df['Top'] + 1
    df = pd.DataFrame(df.values.repeat(df.Bottom - df.Top, axis=0), columns=df.columns)
    df['Top'] = df['Top'] + df.groupby(['ID','Top','Bottom']).cumcount()
    return df[['ID', 'Top', value, 'interval']]

df1_expl = explode_df(df1, 'Value_1')
df2_expl = explode_df(df2, 'Value_2')

df1_expl.head(10)

[Out]:
ID  Top Value_1 interval
0   A   0   CC  3
1   A   1   CC  3
2   A   2   DD  7
3   A   3   DD  7
4   A   4   DD  7
5   A   5   DD  7
6   A   6   DD  7
7   A   7   DD  7
8   A   10  EE  6
9   A   11  EE  6

2 / Объединить df1_expl и df2_expl по идентификатору и вершине

dfcomb_expl = pd.merge(df1_expl, df2_expl, on=['ID','Top'], how='outer')\
    .fillna(0).sort_values(['ID','Top']).reset_index(drop=True)

dfcomb_expl.head(10)

[Out]:
ID  Top Value_1 interval_x  Value_2 interval_y
0   A   0.0 CC  3   XX  5
1   A   1.0 CC  3   XX  5
2   A   2.0 DD  7   XX  5
3   A   3.0 DD  7   XX  5
4   A   4.0 DD  7   YY  3
5   A   5.0 DD  7   YY  3
6   A   6.0 DD  7   0   0
7   A   7.0 DD  7   0   0
8   A   8.0 0   0   ZZ  13
9   A   9.0 0   0   ZZ  13

3 / Aggregate

a) Создать столбец, равный 1 для каждогосохраняемая строка

    dfcomb_expl['keep'] = ((dfcomb_expl['ID'] != dfcomb_expl['ID'].shift()) \
 | (dfcomb_expl['Value_1'] != dfcomb_expl['Value_1'].shift()) \
 | (dfcomb_expl['Value_2'] != dfcomb_expl['Value_2'].shift()))\
.astype(int)

b) отфильтровать сохраняемые строки

dfcomb = dfcomb_expl[dfcomb_expl['keep']==1].reset_index()

c) вычислить основание и значение_комбинации на основе интерваловрассчитывается на шаге 1

dfcomb['Bottom'] = dfcomb['Top'] + dfcomb_expl.groupby(dfcomb_expl['keep'].cumsum())['ID'].transform('count')

dfcomb['Value_combined'] = np.where(dfcomb['interval_x'] == 0, dfcomb['Value_2'], \
                          np.where(dfcomb['interval_y'] == 0, dfcomb['Value_1'], \
                          np.where(dfcomb['interval_x'] < dfcomb['interval_y'], dfcomb['Value_1'], dfcomb['Value_2'])))

df_combine = dfcomb[['ID','Top','Bottom','Value_1','Value_2','Value_combined']]

df_combine

[Out]:
ID  Top Bottom  Value_1 Value_2 Value_combined
0   A   0.0 2.0 CC  XX  CC
1   A   2.0 4.0 DD  XX  XX
2   A   4.0 6.0 DD  YY  YY
3   A   6.0 8.0 DD  0   DD
4   A   8.0 10.0    0   ZZ  ZZ
5   A   10.0    12.0    EE  ZZ  EE
6   A   15.0    17.0    0   ZZ  ZZ
7   B   0.0 2.0 0   NN  NN
8   B   3.0 5.0 FF  NN  NN
9   B   10.0    12.0    FF  MM  FF
10  B   20.0    25.0    0   MM  MM

4 / Примечания В этом решении не учитываются особые случаи, когда Bottom> Top и где для конкретного идентификатора (в df1 или df2) мы имеем2 ряда, включая один и тот же диапазон.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...