Объединение временных рядов временных рядов, в которых дублирующиеся столбцы содержат одинаковые значения - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь объединить несколько фреймов данных, которые содержат данные временных рядов. Эти кадры данных могут иметь до 100 столбцов и примерно 5000 строк. Два примера данных:

df1 = pd.DataFrame({'SubjectID': ['A', 'A', 'B', 'C'], 'Date': ['2010-05-08', '2010-05-10', '2010-05-08', '2010-05-08'], 'Test1':[1, 2, 3, 4], 'Gender': ['M', 'M', 'M', 'F'], 'StudyID': [1, 1, 1, 1]})

df2 = pd.DataFrame({'SubjectID': ['A', 'A', 'A', 'B', 'C'], 'Date': ['2010-05-08', '2010-05-09', '2010-05-10', '2010-05-08', '2010-05-09'], 'Test2': [1, 2, 3, 4, 5], 'Gender': ['M', 'M', 'M', 'M', 'F'], 'StudyID': [1, 1, 1, 1, 1]})

df1
    SubjectID   Date    Test1   Gender  StudyID
0         A     2010-05-08  1   M   1
1         A     2010-05-10  2   M   1
2         B     2010-05-08  3   M   1
3         C     2010-05-08  4   F   1

df2
    SubjectID   Date    Test2   Gender  StudyID
0   A   2010-05-08  1   M   1
1   A   2010-05-09  2   M   1
2   A   2010-05-10  3   M   1
3   B   2010-05-08  4   M   1
4   C   2010-05-09  5   F   1

Мой ожидаемый результат -

SubjectID   Date    Test1   Gender  StudyID     Test2   
0   A   2010-05-08  1.0     M   1.0     1.0     
1   A   2010-05-09  NaN     M   1.0     2.0     
2   A   2010-05-10  2.0     M   1.0     3.0     
3   B   2010-05-08  3.0     M   1.0     4.0     
4   C   2010-05-08  4.0     F   1.0     NaN     
5   C   2010-05-09  NaN     F   1.0     5.0     

Я присоединяюсь к фреймам данных

merged_df = df1.set_index(['SubjectID', 'Date']).join(df2.set_index(['SubjectID', 'Date']), how = 'outer', lsuffix = '_l', rsuffix = '_r').reset_index()

но мой вывод

  SubjectID     Date    Test1   Gender_l    StudyID_l   Test2   Gender_r    StudyID_r
0         A     2010-05-08  1.0     M   1.0     1.0     M   1.0
1         A     2010-05-09  NaN    NaN  NaN     2.0     M   1.0
2         A     2010-05-10  2.0     M   1.0     3.0     M   1.0
3         B     2010-05-08  3.0     M   1.0     4.0     M   1.0
4         C     2010-05-08  4.0     F   1.0     NaN     NaN NaN
5         C     2010-05-09  NaN    NaN  NaN     5.0     F   1.0

Есть ли способ объединить столбцы при объединении фреймов данных, если все значения в обоих фреймах данных равны? Я могу сделать это после слияния, но это утомительно для моих больших наборов данных.

1 Ответ

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

Это зависит от того, как вы хотите реализовать логику разрешения информации, которая может не совсем совпадать. Если бы вы объединили несколько кадров, я думаю, что значение modal подходит. Принимая ваше merged_df мы можем решить это как:

merged_df = merged_df.groupby([x.split('_')[0] for x in merged_df.columns], 1).apply(lambda x: x.mode(1)[0])

         Date Gender  StudyID SubjectID  Test1  Test2
0  2010-05-08      M      1.0         A    1.0    1.0
1  2010-05-09      M      1.0         A    NaN    2.0
2  2010-05-10      M      1.0         A    2.0    3.0
3  2010-05-08      M      1.0         B    3.0    4.0
4  2010-05-08      F      1.0         C    4.0    NaN
5  2010-05-09      F      1.0         C    NaN    5.0

Или, возможно, вы хотите отдать приоритет ненулевому значению в первом кадре, тогда это .combine_first.

df1.set_index(['SubjectID', 'Date']).combine_first(df2.set_index(['SubjectID', 'Date']))

                     Gender  StudyID  Test1  Test2
SubjectID Date                                    
A         2010-05-08      M      1.0    1.0    1.0
          2010-05-09      M      1.0    NaN    2.0
          2010-05-10      M      1.0    2.0    3.0
B         2010-05-08      M      1.0    3.0    4.0
C         2010-05-08      F      1.0    4.0    NaN
          2010-05-09      F      1.0    NaN    5.0

Если вам нужно объединить множество DataFrames, лучше всего использовать reduce от functools.

from functools import reduce

merged_df = reduce(lambda l,r: l.merge(r, on=['SubjectID', 'Date'], how='outer', suffixes=['_l', '_r']), 
                   [df1, df2 ,df1, df2, df2])

У вас будет много перекрывающихся столбцов, но вы все равно сможете их разрешить:

merged_df.groupby([x.split('_')[0] for x in merged_df.columns], 1).apply(lambda x: x.mode(1)[0])

         Date Gender  StudyID SubjectID  Test1  Test2
0  2010-05-08      M      1.0         A    1.0    1.0
1  2010-05-10      M      1.0         A    2.0    3.0
2  2010-05-08      M      1.0         B    3.0    4.0
3  2010-05-08      F      1.0         C    4.0    NaN
4  2010-05-09      M      1.0         A    NaN    2.0
5  2010-05-09      F      1.0         C    NaN    5.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...