使用分组的DataFrame和后置过滤器优化itertools组合

问题描述 投票:0回答:1

我有一个DataFrame作为

Locality     money
1            3
1            4
1            10
1            12
1            15
2            16
2            18

我必须对货币列进行替换组合,并在位置上使用groupby view,在货币差额上使用filter。目标必须像

Locality     money1     money2
1            3          3 
1            3          4
1            4          4
1            10         10
1            10         12
1            10         15
1            12         12
1            12         15
1            15         15
2            16         16
2            16         18
2            18         18

请注意,该组合适用于同一页面上的值和差异小于6的值。

我当前的代码是

from itertools import combinations_with_replacement
import numpy as np
import panda as pd

def generate_graph(input_series, out_cols):
    return pd.DataFrame(list(combinations_with_replacement(input_series, r=2)), columns=out_cols)

df = (
    df.groupby(['Locality'])['money'].apply(
        lambda x: generate_graph(x, out_cols=['money1', 'money2'])
    ).reset_index().drop(columns=['level_1'], errors='ignore')
)

# Ensure the Distance between money is within the permissible limit
df = df.loc[(
    df['money2'] - df['money1'] < 6
)]

问题是,我有一个具有100000行的DataFrame,这花了几乎33秒来处理我的代码。我需要使用numpy来优化我的代码所花费的时间。我正在寻找优化groupby和后置过滤器的方法,这会占用额外的空间和时间。对于示例数据,可以使用此代码生成DataFrame。

# Generate dummy data
t1 = list(range(0, 100000))
b = np.random.randint(100, 10000, 100000)
a = (b/100).astype(int)

df = pd.DataFrame({'Locality': a, 'money': t1})
df = df.sort_values(by=['Locality', 'money'])
python pandas performance numpy itertools
1个回答
0
投票
同时获得运行时间加速和减少空间消耗:

而不是

后过滤-应用扩展函数(例如combine_values),该扩展函数在生成器表达式上生成数据帧,从而产生已过滤(按条件)的组合。

(下面的factor是一个默认参数,它指示提到的

允许的限制

In [48]: def combine_values(values, out_cols, factor=6): ...: return pd.DataFrame(((m1, m2) for m1, m2 in combinations_with_replacement(values, r=2) ...: if m2 - m1 < factor), columns=out_cols) ...: In [49]: df_result = ( ...: df.groupby(['Locality'])['money'].apply( ...: lambda x: combine_values(x, out_cols=['money1', 'money2']) ...: ).reset_index().drop(columns=['level_1'], errors='ignore') ...: )

执行时间

性能:In [50]: %time df.groupby(['Locality'])['money'].apply(lambda x: combine_values(x, out_cols=['money1', 'money2'])).reset_index().drop(columns=['l ...: evel_1'], errors='ignore') CPU times: user 2.42 s, sys: 1.64 ms, total: 2.42 s Wall time: 2.42 s Out[50]: Locality money1 money2 0 1 34 34 1 1 106 106 2 1 123 123 3 1 483 483 4 1 822 822 ... ... ... ... 105143 99 99732 99732 105144 99 99872 99872 105145 99 99889 99889 105146 99 99913 99913 105147 99 99981 99981 [105148 rows x 3 columns]
© www.soinside.com 2019 - 2024. All rights reserved.