Python Pandas groupby с использованием значений в другом кадре данных без цикла for - PullRequest
0 голосов
/ 02 марта 2020

У меня есть код, который работает, но медленно. У меня есть один фрейм данных с данными 'djk', который я хочу суммировать на основе сложной функции groupby. Мне нужно сгруппировать их по 'COUNTERPARTY', 'CURRENCY' и 'Maturity_Bucket'. И 'djk', и 'Maturity_Bucket' являются фреймами данных со множеством строк и столбцов (одинакового размера). Я хочу, чтобы функция groupby использовала соответствующий столбец при группировке. Я решил проблему с for-l oop, но это медленно для больших фреймов данных. Есть ли другой способ, чтобы написать этот код быстрее, удаляя for-l oop?

import pandas as pd
import numpy as np

n = 10000
m = 200
n_name = 25
data_1 = pd.DataFrame(np.random.randint(1, 4, size=(n, m))).astype(int)
data_2 = pd.DataFrame(np.random.randint(100, 200, size=(n, m)))
data_1['COUNTERPARTY'] = (np.random.randint(10, n_name, n)).astype(str)
data_1['COUNTERPARTY'] = 'COUNTERPARTY_' + data_1['COUNTERPARTY']
data_1['CURRENCY'] = (np.random.randint(0, 3, n)).astype(str)
data_1['CURRENCY'] = 'CURRENCY_' + data_1['CURRENCY']


result_pd = pd.DataFrame(0, index=data_1['COUNTERPARTY'].unique(), columns=range(m))


def f_2_support(srs):
    cnt = {k: v for k, v in zip(srs.index.get_level_values(2), srs)}
    a = cnt.get(1, 0)
    b = cnt.get(2, 0)
    c = cnt.get(3, 0)
    return np.sqrt(a ** 2 + b ** 2 + c ** 2 + 1.4 * a * b + 1.4 * b * c + 0.6 * a * c)


for i in range(m):
    df = pd.DataFrame()
    df['COUNTERPARTY'] = data_1['COUNTERPARTY']
    df['CURRENCY'] = data_1['CURRENCY']
    df['djk'] = data_2.loc[:, i]
    df['Maturity_Bucket'] = data_1.loc[:, i]
    result_pd.loc[:, i] = df.groupby(['COUNTERPARTY', 'CURRENCY', 'Maturity_Bucket']).agg({'djk': 'sum'}).groupby(
            ['COUNTERPARTY', 'CURRENCY']).agg({'djk': lambda x: f_2_support(x)}).groupby('COUNTERPARTY').agg(
            {'djk': 'sum'})

Я пытаюсь код ниже, но безуспешно. Возвращает только пустую серию. Что не так?

df_result = pd.DataFrame({i: f_2_new_column(data_2 , data_1, i) for i in range(m)})

def f_2_new_column(data_2 , data_1, n):
    return data_2 .iloc[:, n].groupby([data_1['COUNTERPARTY'], data_1['CURRENCY'], data_1.iloc[:, n]]).agg('sum').groupby(
            [data_1['COUNTERPARTY'], data_1['CURRENCY']]).agg(lambda x: f_2_support(x)).groupby(data_1['COUNTERPARTY']).agg(
            'sum')

1 Ответ

0 голосов
/ 02 марта 2020

Вы пытались это сделать?

df = pd.DataFrame()
df['COUNTERPARTY'] = data_1['COUNTERPARTY']
df['CURRENCY'] = data_1['CURRENCY']
df['Maturity_Bucket'] = data_1.loc[:, 1]

for i in range(m):
df['djk'] = data_2.loc[:, i]
result_pd.loc[:, i] = df.groupby(['COUNTERPARTY', 'CURRENCY', 'Maturity_Bucket']).agg({'djk': 'sum'}).groupby(
        ['COUNTERPARTY', 'CURRENCY']).agg({'djk': lambda x: f_2_support(x)}).groupby('COUNTERPARTY').agg(
        {'djk': 'sum'})

Тот же код, только немного измененный. Каждый раз, когда вы запускали для l oop, вы создавали фрейм данных и снова и снова разрезали столбцы

...