2016-07-20 135 views
0

我有一个数据帧如下 df循环在列和列值子集划分大熊猫据帧

ID color finish duration 
    A1 black smooth 12 
    A2 white matte 8 
    A3 blue smooth 20 
    A4 green matte 10 
    B1 black smooth 12 
    B2 white matte 8 
    B3 blue smooth 
    B4 green  10 
    C1 black smooth 
    C2 white matte 8 
    C3 blue smooth 
    C4 green  10 

我要基于一定的条件下,这种数据框的子集。例如, color= black,finish = smooth,duration = 12,我得到以下数据框。

ID color finish duration score 
A1 black smooth 12 1 
B1 black smooth 12 1 

color= bluefinish = smoothduration = 20,我得到以下数据帧。

ID color finish duration score 
A3 blue smooth 20 1 
B3 blue smooth  0.666667 
C3 blue smooth  0.666667 

得分被计算为数填充列的/总的列数。 我想循环这个熊猫数据框。 以下代码适用于我的2列。

list2 = list(df['color'].unique()) 
list3 = list(df['finish'].unique()) 

df_final = pd.DataFrame() 


for i in range(len(list2)): 
    for j in range(len(list3)): 
     print 'Current Attribute Value:',list2[i],list3[j] 

     gbl["df_"+list2[i]] = df[df.color == list2[i]] 
     gbl["df_" + list2[i] + list3[j]] =   
     gbl["df_"+list2[i]].loc[gbl["df_"+list2[i]].finish == list3[j]] 
     gbl["df_" + list2[i] + list3[j]]['dfattribval'] = list2[i] + list3[j] 
     df_final = df_final.append(gbl["df_" + list2[i] + list3[j]], ignore_index=True) 

但是,我无法循环使用列名称。我想这样做的是,

lista = ['color','finish'] 

df_final = pd.DataFrame() 
for a in range(len(lista)): 
    for i in range(len(list2)): 
    for j in range(len(list3)): 
     print 'Current Attribute Value:',lista[a],list2[i],lista[a+1],list3[j] 
     gbl["df_"+list2[i]] = df[df.lista[a] == list2[i]] 
     gbl["df_" + list2[i] + list3[j]] = gbl["df_"+list2[i]].loc[gbl["df_"+list2[i]].lista[a+1] == list3[j]] 
     gbl["df_" + list2[i] + list3[j]]['dfattribval'] = list2[i] + list3[j] 
     df_final = df_final.append(gbl["df_" + list2[i] + list3[j]], ignore_index=True) 

我得到了明显的错误 -

AttributeError: 'DataFrame' object has no attribute 'lista'.

任何人都会知道如何循环列名和值。非常感谢!

+1

这个问题有太多不一致之处。当你说专栏时,你的意思是行吗? '填充的列数/列的总数'。当你显示'color = blue','finish = smooth','duration = 20'时,显示3行,其中两行没有持续时间20.我失去了解决这个问题的方式。 – piRSquared

+0

另外,真正的最终结果是:单独的dfs还是最后一个附加的df?一个简单的'groupby()'颜色和结束可以实现你的'score'而不需要分开dfs。 – Parfait

+0

@piRSquared,在你的第一个问题上,我正在寻找列数或更具体的细胞填充。例如,在第二个表中,持续时间不会填充第二和第三行。因此,得分是2/3。在第二个问题上,如果您可以将此想象为在Excel中进行筛选,则首先按颜色过滤,然后按完成过滤,最后按持续时间过滤。然后我得到所需的输出。 – Anu

回答

1

不太清楚您的需求,但考虑使用列表理解来排列列表以避免嵌套循环并使用数据框字典。可能scorecalc()应用功能可以调整以适应您的需求:

colorlist = list(df['color'].unique()) 
finishlist = list(df['finish'].unique()) 
durationlist = list(df['duration'].unique()) 

# ALL COMBINATIONS BETWEEN LISTS 
allList = [(c,f, d) for c in colorlist for f in finishlist for d in durationlist] 

def scorecalc(row):  
    row['score'] = row['duration'].count() 
    return(row) 

dfList = []; dfDict = {} 
for i in allList:  
    # SUBSET DFS 
    tempdf = df[(df['color'] == i[0]) & (df['finish']==i[1]) & (df['duration']==i[2])] 

    if len(tempdf) > 0: # FOR NON-EMPTY DFS 
     print('Current Attribute Value:', i[0], i[1], i[2]) 
     tempdf = tempdf.groupby(['color','finish']).apply(scorecalc)   
     tempdf['score'] = tempdf['score']/len(tempdf) 
     print(tempdf) 

     key = str(i[0]) + str(i[1]) + str(i[2]) 
     dfDict[key] = tempdf # DICTIONARY OF DFS (USE pd.DataFrame(list(...)) FOR FINAL) 
     dfList.append(tempdf) # LIST OF DFS (USE pd.concat() FOR FINAL DF) 

# Current Attribute Value: black smooth 12.0 
# ID color finish duration score 
#0 A1 black smooth  12.0 1.0 
#4 B1 black smooth  12.0 1.0 
#Current Attribute Value: white matte 8.0 
# ID color finish duration score 
#1 A2 white matte  8.0 1.0 
#5 B2 white matte  8.0 1.0 
#9 C2 white matte  8.0 1.0 
#Current Attribute Value: blue smooth 20.0 
# ID color finish duration score 
#2 A3 blue smooth  20.0 1.0 
#Current Attribute Value: green matte 10.0 
# ID color finish duration score 
#3 A4 green matte  10.0 1.0 
+0

谢谢@Parfait。 – Anu