我有一个主数据框,其中的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条记录的数据集,此代码将花费大量时间。
答案 0 :(得分:0)
您可以在merge
上使用stack
和reset_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上,它应该比您的方法快