2016-05-15 74 views
0

这是最终的熊猫挑战,在我心中,虽然它可能是基本的一些你在那里......熊猫链接到行的行根据多个条件

我试图连接特定的工作职位与其对应的调查项目。例如,网站A的总裁将归因于调查项目的结果,网站A的响应者提供反馈意见(即“您同意以下声明的程度?”:“我认为网站A的质量是足够的总体””)。

每个站点有5个站点(0到4)。每个工作职位分配给一个或多个工作站的一个或多个工作站。

例如,一个网站的总裁工作在该网站中的所有站点,而承包商可能会在几个站中的2个不同的网站只工作,也许。

调查数据收集在每个站中的每个位点内的质量。

一些调查项目涉及到一个或多个站点内的某些电台。

例如, “位置” 表看起来像这样:

import pandas as pd 
import numpy as np 

pos = pd.DataFrame({'Station(s)':[',1,2,,','0,1,2,3,4'], 
        'Position':['Contractor','President'], 
        'Site(s)':['A,B','A'], 
        'Item(s)':['1','1,2'] 
        }) 

pos[['Position','Site(s)','Station(s)','Item(s)']] 

    Position Site(s)  Station(s) Item(s) 
0 Contractor A,B   ,1,2,,   1 
1 President A   0,1,2,3,4  1,2 

调查数据表看起来像这样:

sd = pd.DataFrame({'Site(s)':['A','B','B','C','A','A'], 
        'Station(s)':[',1,2,,',',1,2,,',',,,,',',1,2,,','0,1,2,,',',,2,,'], 
        'Item 1':[1,1,0,0,1,np.nan], 
        'Item 2':[1,0,0,1,0,1]}) 
sd[['Site','Station(s)','Item 1','Item 2']] 

    Site Station(s) Item 1 Item 2 
0  A  ,1,2,,   1 1 
1  B  ,1,2,,   1 0 
2  B  ,,,,   0 0 
3  C  ,1,2,,   0 1 
4  A  0,1,2,,   1 0 
5  A  ,,2,,   NaN 1 

2侧笔记:

  1. 的由于不重要的原因,项目数据已被编码为1和0。

  2. 的逗号分隔的响应实际上是从柱中冷凝(每站和项的一列)。我只提到,因为如果最好不要浓缩它们,那可以完成(或不完成)。

因此,这里是我所需要的:

这(我认为):

Contractor President Site(s) Station(s) Item 1 Item 2 
0  1   1  A  ,1,2,,  1  1 
1  1   0  B  ,1,2,,  1  0 
2  0   0  B  ,,,,   0  0 
3  0   0  C  ,1,2,,  0  1 
4  0   1  A  0,1,2,,  1  0 
5  1   1  A  ,,2,,   NaN  1 

逻辑:

工程的承建商在现场A和B,只应关联在这些网站工作的受访者。 在这些受访者中,他应该只有那些谁在车站1或2的工作,但没有相关联的也在 任何人(即站0)工作。

因此,在DF2感兴趣的承包商的行是索引0,1,和5 总统的关注行是从指数0,4,5

...,最终,这:

Position Overall% 
0 Contractor 100 
1 President 80 

逻辑:

由于总统涉及项目1和2,有5个号码来考虑:(1和1)从第1项和(1,0,和1)从第2项。 总和项目是4和计数跨项目是5(再次,不计算'NaN'),这得到80%。

因为承包商只关注第1项,所以需要考虑两个数字:1和1 - 不应计算'NaN' - (分别来自感兴趣的行)。因此,总数是2的计数,这是2,这给出100%

在此先感谢!

更新

我知道这工作(top answer just under question),但是这怎么可能被应用到这种情况呢?我想这(只是尝试逻辑的第一部分):

for i in pos['Position']: 
    sd[i]=[x for x in pos.loc['Site(s)'] if x in sd['Site']] 

...但它抛出这个错误:

KeyError: 'the label [Site(s)] is not in the [index]' 

...所以我仍然与它搏斗。

回答

1

如果我理解正确,您想为pos中的每个工作职位添加一列到sd。 (这是首要任务。)

所以,在pos各行指标i(我们遍历行中pos),我们可以创建一个独特的布尔列:

# PSEUDOCODE: 
sd[position_name_i] = (sd['Site'] IS_CONTAINED_IN pos.loc[i,'Site(s)']) and (sd['Station(s)'] IS_CONTAINED_IN pos.loc[i,'Station(s)']) 

我希望这里的逻辑清晰并符合您的目标。

表达式X IS_CONTAINED_IN Y可以以许多不同的方式实现。 (我能想到的X和Y集,然后它的X.subset(Y),或者在位掩码X,Y和bitwise_xor的条款。)

列的名称,position_name_i可能只是一个整数i。 (或者,如果此列包含唯一值,则为pos.loc[i,'Position']

如果这样做了,我们可以执行其他任务。现在,df[df[position_name_i]]将只返回其中position_name_i为真的df的行。

我们遍历所有位置(即pos中的行)。对于每一个位置:

# number of non-nan entries in 'Item 1' and 'Item 2' relevant for the position: 
total = df.loc[df['position_name_i'], ['Item 1', 'Item 2']].count().sum() 
# number of 1's among these entries: 
partial = df.loc[df['position_name_i'], ['Item 1', 'Item 2']].sum().sum() 

最终Overall%对于给定的位置是100*partial/total

+0

你的逻辑听起来很合理。对于电台,必须满足以下两个条件: 1.调查中至少有一个元素(sd ['Station(s)'])必须存在于位置(pos ['Station(s)'])。 2.调查中没有任何元素(sd ['Station(s)'])不能在职位(pos ['Station(s)']中找到 –

+0

对于网站,来自sd ['Site(s) ']必须存在于pos ['Site(s)'] –

+0

我不确定是否理解站点的条件2条件1是“X和Y的交叉点不是空的”,我想,无论如何,无论条件如何,他们总是可以用集合论的语言来写(即作为关于集合,交集,包含等的逻辑句子)。)如果您认为我的回答不太正确,请随时编辑它。请询问是否有不清楚的地方。 – ptrj