替换pandas DataFrame中的列值

时间:2014-04-26 06:04:25

标签: python pandas

我正在尝试替换数据帧的一列中的值。列(“女性”)仅包含“女性”和“男性”的值。

我尝试了以下内容:

w['female']['female']='1'
w['female']['male']='0' 

但是收到以前结果的完全相同的副本。

我希望得到一些类似于以下循环元素的输出。

if w['female'] =='female':
    w['female'] = '1';
else:
    w['female'] = '0';

我查看了陷阱文档(http://pandas.pydata.org/pandas-docs/stable/gotchas.html),但无法弄清楚为什么没有发生。

任何帮助将不胜感激。

13 个答案:

答案 0 :(得分:170)

如果我理解正确,你想要这样的事情:

w['female'] = w['female'].map({'female': 1, 'male': 0})

(在这里,我将值转换为数字而不是包含数字的字符串。如果您真的想要,可以将它们转换为"1""0",但我不确定您为何选择#&# 39;我想要那个。)

您的代码无效的原因是因为在列上使用['female']'female'中的第二个w['female']['female'])并不意味着"选择值为' female'"的行。这意味着选择索引是' female'的行,其中的数据框中可能没有。

答案 1 :(得分:88)

您可以使用loc:

编辑数据框的子集
df.loc[<row selection>, <column selection>]

在这种情况下:

w.loc[w.female != 'female', 'female'] = 0
w.loc[w.female == 'female', 'female'] = 1

答案 2 :(得分:27)

w.female.replace(to_replace=dict(female=1, male=0), inplace=True)

请参阅pandas.DataFrame.replace() docs

答案 3 :(得分:26)

轻微变化:

w.female.replace(['male', 'female'], [1, 0], inplace=True)

答案 4 :(得分:17)

这也应该有效:

w.female[w.female == 'female'] = 1 
w.female[w.female == 'male']   = 0

答案 5 :(得分:9)

您还可以将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,对于那些未在字典中定义的值,它将为空。

答案 6 :(得分:7)

或者,对于这些类型的分配,还有内置函数pd.get_dummies:

w['female'] = pd.get_dummies(w['female'],drop_first = True)

这为您提供了一个包含两列的数据框,每一列都出现在w [&#39; female&#39;]中,其中您放弃了第一列(因为您可以从左边的那一列推断出来) )。新列将自动命名为您替换的字符串。

如果您的分类变量具有两个以上的可能值,则此功能尤其有用。此函数创建区分所有情况所需的虚拟变量。请注意,不要将整个数据框分配到单个列,而是如果[女性&#39;]可能是男性&#39;,&#39;女性&#39;或者&#39;中立&#39;,做这样的事情:

w = pd.concat([w, pd.get_dummies(w['female'], drop_first = True)], axis = 1])
w.drop('female', axis = 1, inplace = True)

然后你会留下两个新栏目,为你提供“女性”的虚拟编码。你摆脱了字符串的列。

答案 7 :(得分:5)

这非常紧凑:

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)

答案 8 :(得分:5)

Series.mapSeries.fillna一起使用

如果您的列中包含的字符串多于femalemale,则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

对于正确方法,我们将mapfillna链接起来,因此我们用原始列中的值填充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

答案 9 :(得分:1)

pandas中还有一个名为factorize的功能,您可以使用该功能自动执行此类工作。它会将标签转换为数字:['male', 'female', 'male'] -> [0, 1, 0]。有关详细信息,请参阅this答案。

答案 10 :(得分:1)

w.female = np.where(w.female=='female', 1, 0)

如果有人正在寻找一个麻木的解决方案。这对于根据条件替换值很有用。 if 和 else 条件都是 np.where() 固有的。如果列除 df.replace() 之外还包含许多唯一值,则使用 'male' 的解决方案可能不可行,所有这些都应替换为 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

答案 11 :(得分:0)

我认为应该在答案中指出您在上面建议的所有方法中使用哪种对象类型:是Series还是DataFrame。

当您通过w.female.w[[2]](假设其中2是您的列号)获得列时,您将获得DataFrame。 因此,在这种情况下,您可以使用.replace之类的DataFrame方法。

当您使用.lociloc时,您将返回Series,而Series没有.replace方法,因此您应使用apply,{{1 }}等。

答案 12 :(得分:0)

dic = {'female':1, 'male':0}
w['female'] = w['female'].replace(dic)

.replace具有一个字典,您可以在其中进行更改并做您想做的或需要做的事。

相关问题