【问题标题】:Python Pandas groupby using values in another dataframe without for-loopPython Pandas groupby 使用另一个数据框中的值而不使用 for 循环
【发布时间】:2020-06-14 19:22:21
【问题描述】:

我有一个可以运行的代码,但速度很慢。 我有一个带有数据“djk”的数据框,我想根据一个复杂的 groupby 函数对其进行总结。 我需要按“对手”、“货币”和“成熟度_桶”对它们进行分组。 'djk' 和 'Maturity_Bucket' 都是具有许多行和列(相同大小)的数据帧。我希望 groupby 函数在分组时使用相应的列。我已经用 for 循环解决了这个问题,但是对于大型数据帧来说它很慢。是否有另一种方法可以更快地编写此代码,删除 for 循环?

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')

【问题讨论】:

    标签: python pandas dataframe optimization pandas-groupby


    【解决方案1】:

    你试过这样做吗?

    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'})
    

    相同的代码只是稍作修改。每次运行 for 循环时,您都在创建一个数据框,并一次又一次地对列进行切片

    【讨论】:

    • 对不起,我在原帖中写错了。我面临的问题是我想在 df['Maturity_Bucket'] = data_1.loc[:, i] 上进行分组,所以每个循环中都有一个新列。
    • 也许您可以尝试在 for 循环中添加 df['Maturity_Bucket'] = data_1.loc[:, i] 并将其他所有内容放在外面。
    • 是的,这就是我自己在代码中所做的。我想知道是否有一种方法可以在没有 for 循环的情况下编写代码。可能是 lambda 的应用或使代码更快的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-15
    • 2011-09-07
    • 2017-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多