优化-将类型集的列拆分为多列

时间:2018-07-21 21:34:54

标签: pandas

我想基于Col1类型的列set的元素创建新列。每个元素都有一个对应的列名,该列名存储在字典中。这是完整的代码:

import numpy as np
import pandas as pd

np.random.seed(123)

N = 10**4 #number of rows in  the dataframe

df = pd.DataFrame({'Cnt': np.random.randint(2,10,N)})

# generate lists of random length
def f(x):
    return set(np.random.randint(101,120,x))
df['Col1'] = df['Cnt'].apply(f)

# dictionary with column names for each element in list
d = {'Item_1':101, 'Item_2':102, 'Item_3':103, 'Item_4':104, 'Item_5':105, 'Item_6':106, 'Item_7':107, 'Item_8':108, 
        'Item_9':109, 'Item_10':110, 'Item_11':111, 'Item_12':112, 'Item_13':113, 'Item_14':114, 'Item_15':115, 'Item_16':116, 
        'Item_17':117, 'Item_18':118, 'Item_19':119, 'Item_20':120}

def elem_in_set(x,e):
    return 1 if e in x else 0

def create_columns(input_data, d):
    df = input_data.copy()
    for k, v in d.items():
        df[k] = df.apply(lambda x: elem_in_set(x['Col1'], v), axis=1)
    return df

%timeit create_columns(df, d)
#5.05 s ± 78.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

问题是生产数据帧有大约40万行,而我的解决方案根本无法很好地扩展-我正在机器上等待大约10分钟。包含所有元素(Col1)的列的类型可以是list而不是set,但这不会提高性能。
有更快的解决方案吗?

1 个答案:

答案 0 :(得分:1)

我对您的create_columns apply做了一个小的更改。看来它现在可以更快地工作了。

import numpy as np
import pandas as pd

np.random.seed(123)

N = 10**4 #number of rows in  the dataframe

df = pd.DataFrame({'Cnt': np.random.randint(2,10,N)})

# generate lists of random length
def f(x):
    return set(np.random.randint(101,120,x))
df['Col1'] = df['Cnt'].apply(f)

# dictionary with column names for each element in list
d = {'Item_1':101, 'Item_2':102, 'Item_3':103, 'Item_4':104, 'Item_5':105, 'Item_6':106, 'Item_7':107, 'Item_8':108, 
        'Item_9':109, 'Item_10':110, 'Item_11':111, 'Item_12':112, 'Item_13':113, 'Item_14':114, 'Item_15':115, 'Item_16':116, 
        'Item_17':117, 'Item_18':118, 'Item_19':119, 'Item_20':120}

def create_columns(input_data, d):
    df = input_data.copy()
    for k, v in d.items():
        df[k] = df.Col1.apply(lambda x: 1 if v in x else 0)
    return df

create_columns(df, d)
#191 ms ± 15.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)