Нюансы слияния нескольких pandas фреймов данных (3+) в ключевой столбец - PullRequest
1 голос
/ 01 апреля 2020

Первый вопрос здесь и длинный - есть несколько вещей, с которыми я сталкиваюсь при объединении и форматировании моих фреймов данных. У меня есть несколько наполовину работающих решений, но я не уверен, что они наилучшие из возможных на основании того, что я хочу.

Вот стандартные форматы кадров данных, которые я объединяю с pandas.

df1 =
      RT   %Area    RRT
0   4.83   5.257  0.509
1   6.76   0.424  0.712
2   7.27   0.495  0.766
3   7.70   0.257  0.811
4   7.79   0.122  0.821
5   9.49  92.763  1.000
6  11.40   0.681  1.201

df2= 
    RT   %Area    RRT
0   4.83   0.731  0.508
1   6.74   1.243  0.709
2   7.28   0.109  0.766
3   7.71   0.287  0.812
4   7.79   0.177  0.820
5   9.50  95.824  1.000
6  11.31   0.348  1.191
7  11.40   1.166  1.200
8  12.09   0.113  1.273

df3 = ...

В настоящее время я использую операцию сокращения для pd.merge_ordered(), как показано ниже, для объединения моих фреймов данных (3+). Этот вид дает то, что я хочу, и было из предыдущего вопроса (pandas трехстороннее объединение нескольких фреймов данных в столбцах ). Я объединяюсь в RRT и хочу, чтобы индексы с одинаковыми значениями RRT были помещены в одну строку - и если значения RRT уникальны для этого набора данных, я хочу, чтобы NaN отсутствовал в других наборах данных.

#The for loop I use to generate the list of formatted dataframes prior to merging
dfs = []
for entry in os.scandir(directory):
    if (entry.path.endswith(".csv")) and entry.is_file():
        entry = pd.read_csv(entry.path, header=None)
        #Block of formatting code removed
        dfs.append(entry.round(2))

dfs = [df1ar,df2ar,df3ar]
df_final = reduce(lambda left,right: pd.merge_ordered(left,right,on='RRT'), dfs)
cols = ['RRT', 'RT_x', '%Area_x', 'RT_y', '%Area_y', 'RT', '%Area']
df_final = df_final[cols]
print(df_final)

      RRT   RT_x  %Area_x   RT_y  %Area_y     RT   %Area
0   0.508    NaN      NaN   4.83    0.731    NaN     NaN
1   0.509   4.83    5.257    NaN      NaN   4.83   5.257
2   0.709    NaN      NaN   6.74    1.243    NaN     NaN
3   0.712   6.76    0.424    NaN      NaN   6.76   0.424
4   0.766   7.27    0.495   7.28    0.109   7.27   0.495
5   0.811   7.70    0.257    NaN      NaN   7.70   0.257
6   0.812    NaN      NaN   7.71    0.287    NaN     NaN
7   0.820    NaN      NaN   7.79    0.177    NaN     NaN
8   0.821   7.79    0.122    NaN      NaN   7.79   0.122
9   1.000   9.49   92.763   9.50   95.824   9.49  92.763
10  1.191    NaN      NaN  11.31    0.348    NaN     NaN
11  1.200    NaN      NaN  11.40    1.166    NaN     NaN
12  1.201  11.40    0.681    NaN      NaN  11.40   0.681
13  1.273    NaN      NaN  12.09    0.113    NaN     NaN

Это работает, но:

  1. Могу ли я вставить мультииндекс, основанный на имени файла кадра данных, с которого поступили данные, и поместить его над соответствующими столбцами? Подобно суффиксной опции, но относится к имени файла и для более чем двух наборов данных. Это лучше сделать до слияния? и если да, то как мне это сделать? (Я включил for l oop, который я использую для создания списка таблиц до слияния.

  2. Является ли это сокращение merge_ordered самым простым способом сделать это?

  3. Можно ли выполнить аналогичное объединение с pd.merge_asof() и использовать значение допуска для точной настройки объединения на основе сходства между значениями RRT? То есть это можно сделать не обрезая данные из более длинных фреймов данных?

Я пробовал вышеизложенное и искал ответы, но я изо всех сил пытаюсь найти самый эффективный способ сделать все, что я хочу.

concat = pd.concat(dfs, axis=1, keys=['A','B','C'])
concat_final = concat.round(3)
print(concat_final)

  A                     B                     C               
      RT   %Area    RRT     RT   %Area    RRT     RT   %Area    RRT
0   4.83   5.257  0.509   4.83   0.731  0.508   4.83   5.257  0.509
1   6.76   0.424  0.712   6.74   1.243  0.709   6.76   0.424  0.712
2   7.27   0.495  0.766   7.28   0.109  0.766   7.27   0.495  0.766
3   7.70   0.257  0.811   7.71   0.287  0.812   7.70   0.257  0.811
4   7.79   0.122  0.821   7.79   0.177  0.820   7.79   0.122  0.821
5   9.49  92.763  1.000   9.50  95.824  1.000   9.49  92.763  1.000
6  11.40   0.681  1.201  11.31   0.348  1.191  11.40   0.681  1.201
7    NaN     NaN    NaN  11.40   1.166  1.200    NaN     NaN    NaN
8    NaN     NaN    NaN  12.09   0.113  1.273    NaN     NaN    NaN

Я также попробовал это - и я получаю мультииндекс, чтобы указать, из какого файла (A, B, C, просто как заполнители) он получен. Однако он явно не слился на основе значения RRT, как я хочу.

  1. Можно ли применить операцию, чтобы изменить ее в формат, аналогичный приведенному выше формату pd.merge_ordered()? Будет ли работать groupby()?

Спасибо!

...