使用另一列作为查找表创建新列时提高性能

时间:2018-06-25 22:52:18

标签: python python-2.7 pandas dataframe

我有一个主数据框,其中的4列代表4种颜色,3行代表3种类型的材料。该帧中的值为1或0,其中1表示正,而0负。 我还有一个非常长的数据框,其中包含多个列,包括一个用于COLOR的列和一个用于MATERIAL的列。对于此框架中的每一行,值将不同。主表指示颜色和材料的哪种组合被认为是阳性的。现在,我想在此框架中创建一个名为“ FAVOR”的新列,以便对于在主表中表示为POSITIVE(值1)的颜色和材质的组合,如果在此长数据框中出现相同的组合,则值应为1,否则为0

我做了一些类似的事情:

for i in pairs:
    main_frame['FAVOR'].loc[(main_frame['Color']==i[0]) & (main_frame['Material']==i[1])]='1'

其中pairs是我使用主表创建的列表,其中每个项目都是一对MATERIAL和COLOR,其值均为1。

以上代码行运行了30分钟以上,我忍耐了一下。 我知道在熊猫中,像这样的逐行操作通常效率低下。但是,有什么更快的方法可以实现我的目标?

编辑:

import pandas as pd
import numpy as np

main_frame = pd.DataFrame({'Color':['g', 'e', 'e', 'k', 's', 'f', 'o', 
             'r', 'g', 'e', 'e', 'k', 's'],'Material':['p', 'r', 'o', 'g', 'r', 'a', 'm', 
                        'm', 'i', 'n', 'g','k','n']})
lookup_table = pd.DataFrame(np.random.choice([1, 0], 56).reshape(7,8),index=['g', 'e', 'k', 's', 'f', 'o', 'r'],columns=['p', 'r', 'o', 'g', 'a', 'm','i', 'n'])
# n = np.random.choice([1, 0], 9).reshape(3,3)
print main_frame
print lookup_table
rows=[]
for i in lookup_table.index:
    rows.append(i)
cols=[]
for j in lookup_table.columns:
    cols.append(j)
pairs=[]
for i in rows:
    for j in cols:
        if lookup_table.loc[i,j]==1:
            pairs.append([i,j])
for i in pairs:
        main_frame['FAVOR'].loc[(main_frame['Color']==i[0]) & (main_frame['Material']==i[1])]='1'

这对于此示例代码非常有效,但是对于我的具有1,000,000条记录的数据集,此代码将花费大量时间。

1 个答案:

答案 0 :(得分:0)

您可以在merge上使用stackreset_index之后再使用lookup_table。首先创建df_stack:

df_stack = (lookup_table.stack().reset_index()
             .rename(columns={'level_0':'Color','level_1':'Material',0:'FAVOR'}))
print (df_stack.head(15))
   Color Material  FAVOR
0      g        p      0
1      g        r      0
2      g        o      1
3      g        g      1
4      g        a      1
5      g        m      0
6      g        i      0
7      g        n      1
8      e        p      0
9      e        r      0
10     e        o      0
11     e        g      0
12     e        a      0
13     e        m      0
14     e        i      0

您可以连续看到lookup_table的一对(行,列)分别与0或1相关联,分别在名为merge的第一列“颜色”和“材质”中:

main_frame = main_frame.merge(df_stack, how='left').fillna(0)

main_frame中的结果是我的随机数0和1:

   Color Material  FAVOR
0      g        p    0.0
1      e        r    0.0
2      e        o    0.0
3      k        g    0.0
4      s        r    1.0
5      f        a    0.0
6      o        m    1.0
7      r        m    1.0
8      g        i    0.0
9      e        n    0.0
10     e        g    0.0
11     k        k    0.0
12     s        n    0.0

在大型df上,它应该比您的方法快