2017-04-20 3 views
2

に基づいて更新行私はパンダのデータフレームを有する、DFは、のように:Pythonのパンダ:別の行の値

name | grade | grade_type 
--------------------------- 
sarah | B  | letter 
alice | A  | letter 
eliza | C  | letter 
beth | 76 | numeral 
jones | 90 | numeral 
df

のすべての値は、数値を含む文字列です。私が取得し、grade_type列をチェックするに基づいて、手紙にgrade数値を変換したい:

name | grade | grade_type 
--------------------------- 
sarah | B  | letter 
alice | A  | letter 
eliza | C  | letter 
beth | B  | numeral 
jones | A  | numeral 

完全にするために、数字・ツー・レターグレードの変換は、次のとおりです。

A: grade > 80 
B: 70 < grade <= 80 
C: 60 < grade <= 70 

なぜdoesnのこの作品はありませんか?

for index, row in df.iterrows(): 
    if row.grade_type == "numeral": 
    grade_val = int(row.grade.values[0]) 
    if grade_val > 80: 
     row.grade = "A" # This assignment doesn't update row.grade! 
    elif... 

代替はdf.apply(...lambda:...)を使用しているが、私たちはgrade値を更新するかどうかを決定する前にgrade_type列をチェックする必要があるため、それをやってのけるする方法があまりにもわかりません。

答えて

2

DataFrameが更新されない理由は、iterrows():から返された行がコピーであるためです。あなたはそのコピーに取り組んでいます。

あなたはindexiterrowsから返されると、直接データフレームを操作する使用することができます。

for index, row in df.iterrows(): 
    grade_val = int(row.grade.values[0]) 
    if grade_val > 80: 
     df.loc[index, 'grade'] = 'A' 
    ... 

それとも、あなたがdf.apply()を使用し、それをカスタム関数を渡すことができたとして:

def get_grades(x): 
    if x['grade_type'] == 'letter': 
     return(x['grade_val']) 
    if x['grade_val'] > 80: 
     return "A" 
    ... 


df['grade'] = df.apply(lambda x: get_grades(x), axis=1) 

あなたがすることができますもをあなたのラムダにifelseを使用して、x['grade_type']が次のような数値であるかどうかを確認してください。読みやすいようにしてください。

def get_grades(grade_val): 
    if grade_val > 80: 
     return "A" 
    ... 

df['grade'] = df.apply(lambda x: get_grades(x['grade']) 
         if x['grade_type'] == 'numeral' else x['grade'], axis=1) 
関連する問題