объединить два кадра данных с некоторыми общими столбцами, где объединение общих должно быть пользовательской функцией - PullRequest
0 голосов
/ 08 октября 2018

мой вопрос очень похож на Объединить панду данных с операцией столбца , но это не отвечает моим потребностям.

Допустим, у меня есть два кадра данных, например (обратите внимание, что кадр данныхсодержимое может быть числом с плавающей точкой вместо логических значений):

left = pd.DataFrame({0: [True, True, False], 0.5: [False, True, True]}, index=[12.5, 14, 15.5])
right = pd.DataFrame({0.7: [True, False, False], 0.5: [True, False, True]}, index=[12.5, 14, 15.5])

вправо

        0.5    0.7
12.5   True   True
14.0  False  False
15.5   True  False

влево

        0.0    0.5
12.5   True  False
14.0   True   True
15.5  False   True

Как видите, они имеют одинаковые индексы и одинстолбца является общим.В реальной жизни может быть больше общих столбцов, таких как еще один на 1.0 или другие числа, которые еще не определены, и больше уникальных столбцов на каждой стороне.Мне нужно объединить два кадра данных так, чтобы все уникальные столбцы были сохранены, а общие столбцы были объединены с использованием определенной функции, например, логического ИЛИ для этого примера, тогда как индексы всегда идентичны для обоих кадров данных.

Таким образом,результат должен быть:

результат

        0.0   0.5    0.7
12.5   True  True   True
14.0   True  True  False
15.5  False  True  False

В реальной жизни будет более двух фреймов данных, которые необходимо объединить, но они могут быть последовательно объединены один за другим в пустой первыйдатафрейм.

Я чувствую, что pandas.combine может сработать, но я не могу понять это из документации.У кого-нибудь будет предложение, как сделать это за один или несколько шагов.

1 Ответ

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

Вы можете объединить кадры данных, а затем сгруппировать имена столбцов, чтобы применить операцию к столбцам с одинаковыми именами: в этом случае вы можете избежать взятия суммы и затем типизировать обратно в bool, чтобы получить операцию or.

import pandas as pd

df = pd.concat([left, right], 1)
df.groupby(df.columns, 1).sum().astype(bool)

Выходные данные:

        0.0   0.5    0.7
12.5   True  True   True
14.0   True  True  False
15.5  False  True  False

Если вам нужно посмотреть, как это сделать в менее конкретном случае, то снова просто сгруппируйте по столбцам и примените что-нибудьдля сгруппированного объекта над axis=1

df = pd.concat([left, right], 1)
df.groupby(df.columns, 1).apply(lambda x: x.any(1))
#        0.0   0.5    0.7
#12.5   True  True   True
#14.0   True  True  False
#15.5  False  True  False

Кроме того, вы можете определить пользовательскую функцию объединения.Вот тот, который добавляет дважды левый кадр в 4 раза правый кадр.Если есть только один столбец, он возвращает 2х левый кадр.

Пример данных

влево:

      0.0  0.5
12.5    1   11
14.0    2   17
15.5    3   17

вправо:

      0.7  0.5
12.5    4    2
14.0    4   -1
15.5    5    5

Код

def my_func(x):
    try:
        res = x.iloc[:, 0]*2 + x.iloc[:, 1]*4
    except IndexError:
        res = x.iloc[:, 0]*2
    return res

df = pd.concat([left, right], 1)
df.groupby(df.columns, 1).apply(lambda x: my_func(x))

Вывод:

      0.0  0.5  0.7
12.5    2   30    8
14.0    4   30    8
15.5    6   54   10

Наконец, если вы хотите сделать это последовательно, вам следует использовать reduce.Здесь я объединю 5 DataFrames с вышеуказанной функцией.(Я просто повторю правильный кадр 4x для примера)

from functools import reduce

def my_comb(df_l, df_r, func):
    """ Concatenate df_l and df_r along axis=1. Apply the
    specified function.
    """
    df = pd.concat([df_l, df_r], 1)
    return df.groupby(df.columns, 1).apply(lambda x: func(x))

reduce(lambda dfl, dfr: my_comb(dfl, dfr, func=my_func), [left, right, right, right, right])
#      0.0  0.5  0.7
#12.5   16  296  176
#14.0   32  212  176
#15.5   48  572  220
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...