2017-07-26 141 views
0

有关熊猫数据框条件循环的问题。数据框架的利益是巨大的。我们有不同时间的学生姓名和考试成绩(请参阅下文)。如果他/她的分数在任何测试中低于75,则认为该学生失败,否则通过。我无法有效地做到这一点。据帧:有条件循环:熊猫Python

score = {'student_name': ['Jiten', 'Jac', 'Ali', 'Steve', 'Dave', 'James'], 
    'test_quiz_1': [74, 81, 84, 67, 59, 96], 
'test_quiz_2': [76, np.NaN, 99, 77, 53, 69], 
'test_mid_term': [76, 88, 84, 67, 58, np.NaN], 
'test_final_term': [76, 78, 89, 67, 58, 96]} 

df = pd.DataFrame(score, columns = ['student_name', 'test_quiz_1', 'test_quiz_2', 'test_mid_term', 'test_final_term']) 

我的方法:(基于雅克·克瓦姆的回答修改)

df.test_quiz_1 > 70 

这(^)给了我的位置,其中具体的学生不及格。其他测试(df.test_quiz_2,...)可以重复相同的操作。最后,如果考生在任何考试中失败,我都需要将这些全部合并成一个最后一列,在那里学生失败。

编辑:我对python和pandas了解甚少。我正在编写关于如何在C/C++中实现的伪代码。

for student in student_list: 
    value=0 
    for i in range (no_of_test): 
     if (score<75): 
      value=value+1 
     else: 
      continue 
    if(value>0): 
     student[status]=fail 
    else: 
     student[status]=pass 

上面只是一个伪代码。我不会创建任何附加列来标记学生是否在任何测试中失败。使用熊猫可以在Python中实现类似的东西吗?

请指教。

回答

0

我觉得这适合您的需要:

cols = df.columns.drop("student_name").tolist() 
df["PassOrFail"] = df[cols].fillna(0).lt(75).any(1) 

for i in cols: 
    df[i+"_"] = df[i].fillna(0).lt(75) 

说明

首先我们创建有关列的列表:

['test_quiz_1', 'test_quiz_2', 'test_mid_term', 'test_final_term'] 

然后,我们创建一个新的col [“PassOrFail”],用于检查数据帧是否为conatainin g相关列(np.Nan = 0)低于75.

最后,使用True或False值为每个相关列创建一个新列。

更新

比方说,我们只有在获得真或假有兴趣,然后将下面的代码应该是足够了:

cols = df.columns.drop("student_name").tolist() 
results = df[cols].fillna(0).lt(75).any(1).tolist() 
(~pd.Series(results,index=df["student_name"])).to_dict() 

输出:

{'Ali': True, 
'Dave': False, 
'Jac': False, 
'James': False, 
'Jiten': False, 
'Steve': False} 
+0

谢谢。请检查问题的编辑部分。 –

+0

@XingfangLee更新了我的答案。这是你要求的吗? –

+0

是的。感谢您的回复。 –

2

您应该使用从numpy继承的pandas矢量操作来代替循环。例如,以标记通过test_quiz_1人:

df.test_quiz_1 > 70 

,并提供:

0  True 
1  True 
2  True 
3 False 
4 False 
5  True 
Name: test_quiz_1, dtype: bool 

编辑:继续让我们说你有3个试验用5名学生,并表示它作为一个布尔值数据框:

 0  1  2 
0 True True False 
1 True True True 
2 True False False 
3 True False True 
4 True False False 

如果学生通过了所有的测试,通过df.all(axis=1)来检查他们是否通过了所有测试,测试结果如下:

0 False 
1  True 
2 False 
3 False 
4 False 
dtype: bool 

只有学生1通过了这种情况。

+0

感谢。我根据你的回答修改了这个问题。请指教。 –

+0

再次感谢。我们不能避免在数据框中创建额外的列(上面的布尔数据框中的参考列0,1,2)。 –

1
df.set_index('student_name').lt(75).any(1) 
# `lt` is the method version of `<` 
# this identifies students that received 
# a score less than 75 on any of the tests. 

student_name 
Jiten  True 
Jac  False 
Ali  False 
Steve  True 
Dave  True 
James  True 
dtype: bool