[英]Replacing column values in a pandas DataFrame
我正在尝试替换数据帧的一列中的值。 列 ('female') 仅包含值 'female' 和 'male'。
我尝试了以下方法:
w['female']['female']='1'
w['female']['male']='0'
但收到与先前结果完全相同的副本。
理想情况下,我希望获得一些类似于以下循环元素的输出。
if w['female'] =='female':
w['female'] = '1';
else:
w['female'] = '0';
我已经查看了 gotchas 文档( http://pandas.pydata.org/pandas-docs/stable/gotchas.html ),但无法弄清楚为什么什么也没发生。
任何帮助将不胜感激。
如果我理解正确,你想要这样的东西:
w['female'] = w['female'].map({'female': 1, 'male': 0})
(这里我将值转换为数字而不是包含数字的字符串。如果您真的需要,您可以将它们转换为"1"
和"0"
,但我不确定您为什么想要那样。)
原因您的代码不工作是因为使用['female']
柱(第二'female'
在你的w['female']['female']
并不意味着“选择行,其中的值是'女性'”。 这意味着选择索引为“女性”的行,其中在您的 DataFrame 中可能没有任何行。
您可以使用 loc 编辑数据帧的子集:
df.loc[<row selection>, <column selection>]
在这种情况下:
w.loc[w.female != 'female', 'female'] = 0
w.loc[w.female == 'female', 'female'] = 1
w.female.replace(to_replace=dict(female=1, male=0), inplace=True)
轻微变化:
w.female.replace(['male', 'female'], [1, 0], inplace=True)
这也应该有效:
w.female[w.female == 'female'] = 1
w.female[w.female == 'male'] = 0
您还可以将apply
与.get
一起使用,即
w['female'] = w['female'].apply({'male':0, 'female':1}.get)
:
w = pd.DataFrame({'female':['female','male','female']})
print(w)
数据框w
:
female
0 female
1 male
2 female
使用apply
替换字典中的值:
w['female'] = w['female'].apply({'male':0, 'female':1}.get)
print(w)
结果:
female
0 1
1 0
2 1
注意:如果数据框中列的所有可能值都在字典中定义,则应使用字典apply
,否则字典中未定义的值将为空。
这是非常紧凑的:
w['female'][w['female'] == 'female']=1
w['female'][w['female'] == 'male']=0
另一个不错的:
w['female'] = w['female'].replace(regex='female', value=1)
w['female'] = w['female'].replace(regex='male', value=0)
或者,对于这些类型的赋值,有内置函数 pd.get_dummies:
w['female'] = pd.get_dummies(w['female'],drop_first = True)
这为您提供了一个包含两列的数据框,一个用于 w['female'] 中出现的每个值,您删除其中的第一列(因为您可以从剩下的列中推断出它)。 新列将自动命名为您替换的字符串。
如果您有具有两个以上可能值的分类变量,这将特别有用。 该函数创建了区分所有情况所需的尽可能多的虚拟变量。 请注意,不要将整个数据框分配给单个列,而是如果 w['female'] 可以是 'male'、'female' 或 'neutral',请执行以下操作:
w = pd.concat([w, pd.get_dummies(w['female'], drop_first = True)], axis = 1])
w.drop('female', axis = 1, inplace = True)
然后你会留下两个新的列,给你“女性”的虚拟编码,你摆脱了带有字符串的列。
Series.map
和Series.fillna
如果您的列包含的字符串多于female
和male
,则在这种情况下Series.map
将失败,因为它会为其他值返回NaN
。
这就是为什么我们必须用fillna
链接它:
.map
失败的示例:
df = pd.DataFrame({'female':['male', 'female', 'female', 'male', 'other', 'other']})
female
0 male
1 female
2 female
3 male
4 other
5 other
df['female'].map({'female': '1', 'male': '0'})
0 0
1 1
2 1
3 0
4 NaN
5 NaN
Name: female, dtype: object
对于正确的方法,我们将map
与fillna
,因此我们用原始列中的值填充NaN
:
df['female'].map({'female': '1', 'male': '0'}).fillna(df['female'])
0 0
1 1
2 1
3 0
4 other
5 other
Name: female, dtype: object
w.replace({'female':{'female':1, 'male':0}}, inplace = True)
上面的代码将 'female' 替换为 1,'male' 替换为 0,仅在 'female' 列中
w.female = np.where(w.female=='female', 1, 0)
如果有人正在寻找一个 numpy 解决方案。 这对于根据条件替换值很有用。 if 和 else 条件都是np.where()
固有的。 如果列除'male'
之外还包含许多唯一值,则使用df.replace()
的解决方案可能不可行,所有这些值都应替换为0
。
另一种解决方案是连续使用df.where()
和df.mask()
。 这是因为它们都没有实现 else 条件。
w.female.where(w.female=='female', 0, inplace=True) # replace where condition is False
w.female.mask(w.female=='female', 1, inplace=True) # replace where condition is True
我认为在回答中应该指出您在上面建议的所有方法中获得哪种类型的对象:它是 Series 还是 DataFrame。
当你得到w.female.
或w[[2]]
(假设 2 是您的列数),您将返回 DataFrame。 因此,在这种情况下,您可以使用 DataFrame 方法,例如.replace
。
当您使用.loc
或iloc
您会返回 Series,而 Series 没有.replace
方法,因此您应该使用apply
、 map
等方法。
dic = {'female':1, 'male':0}
w['female'] = w['female'].replace(dic)
.replace 有一个字典作为参数,您可以在其中更改并执行您想要或需要的任何操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.