Объединение двух столбцов в фрейме данных, который содержит словари, и сохранение его в другом столбце фрейма данных. - PullRequest
0 голосов
/ 06 января 2020

У меня есть фрейм данных df, который имеет два столбца a и b, который содержит словари, и я хочу объединить эти два словаря и сохранить объединенные словари в новых столбцах c. Одна точка выборки данных:

df :

     a                 b                         c
------------------------------------------------------------
{x:{y:{z:u}}     {w:{f:{h:l}}        {x:{y:{z:u}},{w:{f:{h:l}}

У меня есть a и b, и я хочу c. У меня есть функция, которая объединяет два словаря, но я не могу назначить словари слияния для столбца c.

Функция, которая у меня есть для объединения двух словарей:

# Function for merging two dictionaries and adding values if keys are same
def merge_and_add(dict1, dict2):
    # We loop over the key and value pairs of the second dictionary...
    for k, v in dict2.items():
        # If the key is also found in the keys of the first dictionary, and...
        if k in dict1.keys():
            # If  the value is a dictionary...
            if isinstance(v, dict):
                # we pass this value to the merge_and_add function, together with the value of first dictionary with
                # the same key and we overwrite this value with the output.
                dict1[k] = merge_and_add(dict1[k], v)
            # If the value is an integer...
            elif isinstance(v, int):
                # we add the value of the key value pair of the second dictionary to the value of the first 
                # dictionary with the same key.
                dict1[k] = dict1[k] + v
        # If the key is not found, the key and value of the second should be appended to the first dictionary
        else:
            dict1[k] = v
    # return the first dictionary
    return dict1

Я пытаюсь следующее, но это не работает:

df_curr_hist['latest'] = np.nan
def latest(df):
    idx = 0
    while idx < len(df):
        curr_dict = df.iloc[idx]['current']
        hist_dict = df.iloc[idx]['history']
        df.latest[idx] = merge_and_add(curr_dict, hist_dict)
    return df

1 Ответ

1 голос
/ 06 января 2020

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

x = {'a':{'b':2}}
y = {'c':{'e':4}}

e = pd.DataFrame({'a':[x], 'b': [y]})

def merge_and_add(x, y):

    dict1 = x.copy()
    dict2 = y.copy()
    # We loop over the key and value pairs of the second dictionary...
    for k, v in dict2.items():
        # If the key is also found in the keys of the first dictionary, and...
        if k in dict1.keys():
            # If  the value is a dictionary...
            if isinstance(v, dict):
                # we pass this value to the merge_and_add function, together with the value of first dictionary with
                # the same key and we overwrite this value with the output.
                dict1[k] = merge_and_add(dict1[k], v)
            # If the value is an integer...
            elif isinstance(v, int):
                # we add the value of the key value pair of the second dictionary to the value of the first 
                # dictionary with the same key.
                dict1[k] = dict1[k] + v
        # If the key is not found, the key and value of the second should be appended to the first dictionary
        else:
            dict1[k] = v
    # return the first dictionary
    return dict1


e['c'] = e.apply(lambda x : merge_and_add(x.a, x.b), axis = 1)

Окончательный вывод выглядит как

                 a                b                               c
0  {'a': {'b': 2}}  {'c': {'e': 4}}  {'a': {'b': 2}, 'c': {'e': 4}}

...