【问题标题】:Optimising itertools combination with grouped DataFrame and post filter使用分组 DataFrame 和后过滤器优化 itertools 组合
【发布时间】:2020-06-16 21:56:56
【问题描述】:

我有一个 DataFrame 作为

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

我必须使用 groupby 视图 对地区性和 过滤器 进行货币差异的替换。目标必须像

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

请注意,该组合适用于相同 Locality 上的值和差异小于 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】:

    同时获得运行时间加速和减少空间消耗:

    代替后过滤 - 应用扩展函数(比如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]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-07
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2017-07-03
      • 2020-08-19
      • 1970-01-01
      相关资源
      最近更新 更多