熊猫列内的映射值
Posted
技术标签:
【中文标题】熊猫列内的映射值【英文标题】:Mapping values inside pandas column 【发布时间】:2019-01-02 18:24:14 【问题描述】:我使用下面的代码将 S 列中的 2 个值映射为 0,但它不起作用。关于如何解决这个问题的任何建议? 注意:我想在地图内实现一个外部函数。
df = pd.DataFrame(
'Age': [30,40,50,60,70,80],
'Sex': ['F','M','M','F','M','F'],
'S' : [1,1,2,2,1,2]
)
def app(value):
for n in df['S']:
if n == 1:
return 1
if n == 2:
return 0
df["S"] = df.S.map(app)
【问题讨论】:
【参考方案1】:你可以这样做:
import numpy as np
df['S'] = np.where(df['S'] == 2, 0, df['S'])
【讨论】:
【参考方案2】:>>>df = pd.DataFrame('Age':[30,40,50,60,70,80],'Sex':
['F','M','M','F','M','F'],'S':
[1,1,2,2,1,2])
>>> def app(value):
return 1 if value == 1 else 0
# or app = lambda value : 1 if value == 1 else 0
>>> df["S"] = df["S"].map(app)
>>> df
Age S Sex
Age S Sex
0 30 1 F
1 40 1 M
2 50 0 M
3 60 0 F
4 70 1 M
5 80 0 F
【讨论】:
【参考方案3】:不要使用 apply
,只需使用 loc
来分配值:
df.loc[df.S.eq(2), 'S'] = 0
Age Sex S
0 30 F 1
1 40 M 1
2 50 M 0
3 60 F 0
4 70 M 1
5 80 F 0
如果您需要更高性能的选项,请使用 np.select
。这也更具可扩展性,因为您可以随时添加更多条件:
df['S'] = np.select([df.S.eq(2)], [0], 1)
【讨论】:
【参考方案4】:使用eq
创建一个布尔系列并将该布尔系列转换为astype
的int:
df['S'] = df['S'].eq(1).astype(int)
或
df['S'] = (df['S'] == 1).astype(int)
输出:
Age Sex S
0 30 F 1
1 40 M 1
2 50 M 0
3 60 F 0
4 70 M 1
5 80 F 0
【讨论】:
嗯,这比通过loc
分配要快得多
@user3483203 你可以试试 mask,应该更快:-) df.S.mask(df.S>1,0)
是的,快得多,我需要使用mask
more :D【参考方案5】:
使用矢量化 numpy 操作:
df['S'] = np.abs(df['S'] - 2)
并在面试和 SO 答案中脱颖而出 :)
【讨论】:
【参考方案6】:您可以按如下方式使用 .replace: df["S"] = df["S"].replace([2], 0) 这将在一行中将所有 2 个值替换为 0
【讨论】:
【参考方案7】:如果您只想更改等于 2 的值,可以使用pd.DataFrame.loc
:
df.loc[df['S'] == 0, 'S'] = 0
不推荐pd.Series.apply
,这只是一个隐蔽、低效的循环。
【讨论】:
【参考方案8】:您已经接近了,但您需要进行一些更正。既然要使用函数,请删除for
循环并将n
替换为value
。此外,请使用 apply
而不是 map
。 Apply
一次对整个列进行操作。请参阅此answer,了解如何正确使用apply
vs applymap
vs map
def app(value):
if value == 1:
return 1
elif value == 2:
return 0
df['S'] = df.S.apply(app)
Age Sex S
0 30 F 1
1 40 M 1
2 50 M 0
3 60 F 0
4 70 M 1
5 80 F 0
【讨论】:
以上是关于熊猫列内的映射值的主要内容,如果未能解决你的问题,请参考以下文章