如何根据另一列中的值将函数应用于 Pandas 中的列?
How to apply a function to a column in Pandas depending on the value in another column?
提前感谢您的阅读。
我有一个数据框:
df = pd.DataFrame({'Words':[{'Sec': ['level']},{'Sec': ['levels']},{'Sec': ['level']},{'Und': ['ba ']},{'Pro': ['conf'],'ProAbb': ['cth']}],'Conflict':[None,None,None,None,'Match Conflict']})
Conflict Words
0 None {u'Sec': [u'level']}
1 None {u'Sec': [u'levels']}
2 None {u'Sec': [u'level']}
3 None {u'Und': [u'ba ']}
4 Match Conflict {u'ProAbb': [u'cth'], u'Pro': [u'conf']}
我想应用一个例程,对于 'Words'
中的每个元素,检查是否 Conflict = 'Match Conflict'
,如果是,则对 'Words'
中的值应用一些函数。
例如,使用以下占位符函数:
def func(x):
x = x.clear()
return x
我写:
df['Words'] = df[df['Conflict'] == 'Match Conflict']['Words'].apply(lambda x: func(x))
我的预期输出是:
Conflict Words
0 None {u'Sec': [u'level']}
1 None {u'Sec': [u'levels']}
2 None {u'Sec': [u'level']}
3 None {u'Und': [u'ba ']}
4 Match Conflict None
相反,我得到:
Conflict Words
0 None NaN
1 None NaN
2 None NaN
3 None NaN
4 Match Conflict None
该函数仅应用于具有 Conflict = 'Match Conflict'
的行,但以其他行为代价(全部变为 None
。我假设其他行将保持不变;显然这事实并非如此。
您能解释一下我如何在不删除 Words
列中的所有信息的情况下实现我想要的输出吗?我相信答案可能在于 np.where
,但我无法完成这项工作,这是我能想到的最好的办法。
非常感谢任何帮助。谢谢。
您应该重写函数以处理所有行:
def func(x, match):
if x['Conflict'] == match:
return None
return x['Words']
df['Words'] = df.apply(lambda row: func(row, 'Match Conflict'), axis=1)
您可以尝试只更新符合条件的行 .loc
:
df.loc[df['Conflict'] == 'Match Conflict', 'Words'] = df.loc[df['Conflict'] == 'Match Conflict', 'Words'].apply(lambda x: func(x))
您也可以按照您的描述使用where
,
condition = df.Conflict != 'Match Conflict'
df['Words'] = df.Words.where(condition, None)
Conflict Words
0 None {u'Sec': [u'level']}
1 None {u'Sec': [u'levels']}
2 None {u'Sec': [u'level']}
3 None {u'Und': [u'ba ']}
4 Match Conflict None
假设一个占位符
def func(x):
x = x.clear()
return x
然后我们可以使用布尔索引并应用以获得所需的输出。
df.ix[df['Conflict']=='Match Conflict', 'Words'].apply(func)
我想提供一个简洁的 one-liner 但我来不及了:,(
提前感谢您的阅读。
我有一个数据框:
df = pd.DataFrame({'Words':[{'Sec': ['level']},{'Sec': ['levels']},{'Sec': ['level']},{'Und': ['ba ']},{'Pro': ['conf'],'ProAbb': ['cth']}],'Conflict':[None,None,None,None,'Match Conflict']})
Conflict Words
0 None {u'Sec': [u'level']}
1 None {u'Sec': [u'levels']}
2 None {u'Sec': [u'level']}
3 None {u'Und': [u'ba ']}
4 Match Conflict {u'ProAbb': [u'cth'], u'Pro': [u'conf']}
我想应用一个例程,对于 'Words'
中的每个元素,检查是否 Conflict = 'Match Conflict'
,如果是,则对 'Words'
中的值应用一些函数。
例如,使用以下占位符函数:
def func(x):
x = x.clear()
return x
我写:
df['Words'] = df[df['Conflict'] == 'Match Conflict']['Words'].apply(lambda x: func(x))
我的预期输出是:
Conflict Words
0 None {u'Sec': [u'level']}
1 None {u'Sec': [u'levels']}
2 None {u'Sec': [u'level']}
3 None {u'Und': [u'ba ']}
4 Match Conflict None
相反,我得到:
Conflict Words
0 None NaN
1 None NaN
2 None NaN
3 None NaN
4 Match Conflict None
该函数仅应用于具有 Conflict = 'Match Conflict'
的行,但以其他行为代价(全部变为 None
。我假设其他行将保持不变;显然这事实并非如此。
您能解释一下我如何在不删除 Words
列中的所有信息的情况下实现我想要的输出吗?我相信答案可能在于 np.where
,但我无法完成这项工作,这是我能想到的最好的办法。
非常感谢任何帮助。谢谢。
您应该重写函数以处理所有行:
def func(x, match):
if x['Conflict'] == match:
return None
return x['Words']
df['Words'] = df.apply(lambda row: func(row, 'Match Conflict'), axis=1)
您可以尝试只更新符合条件的行 .loc
:
df.loc[df['Conflict'] == 'Match Conflict', 'Words'] = df.loc[df['Conflict'] == 'Match Conflict', 'Words'].apply(lambda x: func(x))
您也可以按照您的描述使用where
,
condition = df.Conflict != 'Match Conflict'
df['Words'] = df.Words.where(condition, None)
Conflict Words
0 None {u'Sec': [u'level']}
1 None {u'Sec': [u'levels']}
2 None {u'Sec': [u'level']}
3 None {u'Und': [u'ba ']}
4 Match Conflict None
假设一个占位符
def func(x):
x = x.clear()
return x
然后我们可以使用布尔索引并应用以获得所需的输出。
df.ix[df['Conflict']=='Match Conflict', 'Words'].apply(func)
我想提供一个简洁的 one-liner 但我来不及了:,(