Python 将数据帧中的值从字符串映射到int(例如,带有性别)
我有一个名为Python 将数据帧中的值从字符串映射到int(例如,带有性别),python,pandas,mapping,Python,Pandas,Mapping,我有一个名为df_base的数据帧,看起来像这样。正如你所看到的,有一个名为Sex的专栏,它是男性或女性。我想将这些值分别映射到0和1 +---+-------------+----------+--------+---------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ | | Passe
df_base
的数据帧,看起来像这样。正如你所看到的,有一个名为Sex
的专栏,它是男性
或女性
。我想将这些值分别映射到0和1
+---+-------------+----------+--------+---------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+
| | PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked |
+---+-------------+----------+--------+---------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+
| 0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.25 | NaN | S |
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
| 2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.925 | NaN | S |
| 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1 | C123 | S |
| 4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.05 | NaN | S |
+---+-------------+----------+--------+---------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+
我在StackOverflow上看到了一些方法,但我想知道最有效的方法是执行以下映射:
+---------+---------+
| Old Sex | New Sex |
+---------+---------+
| male | 0 |
| female | 1 |
| female | 1 |
| female | 1 |
| male | 0 |
+---------+---------+
我用这个:
df_base['Sex']。替换(['male','female'],[0,1],inplace=True)
。。。但我忍不住觉得这有点粗制滥造。有更好的方法吗?也有使用
.loc
的方法,但是它在数据帧的行中循环,所以效率较低,对吧?我认为,如果列Sex
中有男性和女性的话,字典的使用会更好/更快:
df_base['Sex'] = df_base['Sex'].map(dict(zip(['male','female'],[0,1]))
什么是一样的:
df_base['Sex'] = df_base['Sex'].map({'male': 0,'female': 1})
如果仅存在女性
和男性
值,则解决方案将布尔掩码转换为整数真/假
转换为1,0
:
df_base['Sex'] = (df_base['Sex'] == 'female').astype(int)
性能:
np.random.seed(2019)
import perfplot
def ma(df):
df = df.copy()
df['Sex_new'] = df['Sex'].map({'male': 0,'female': 1})
return df
def rep1(df):
df = df.copy()
df['Sex'] = df['Sex'].replace(['male','female'],[0,1])
return df
def nwhere(df):
df = df.copy()
df['Sex_new'] = np.where(df['Sex'] == 'male', 0, 1)
return df
def mask1(df):
df = df.copy()
df['Sex_new'] = (df['Sex'] == 'female').astype(int)
return df
def mask2(df):
df = df.copy()
df['Sex_new'] = (df['Sex'].values == 'female').astype(int)
return df
def make_df(n):
df = pd.DataFrame({'Sex': np.random.choice(['male','female'], size=n)})
return df
结论:
如果仅替换2个值是最慢的replace
,numpy.where、map和mask
。要提高性能,请将numpy数组与值进行比较
也取决于数据,所以最好用真实数据进行测试。我认为,如果列中性别中只有男性和女性存在,那么字典使用起来更好/更快:
df_base['Sex'] = df_base['Sex'].map(dict(zip(['male','female'],[0,1]))
什么是一样的:
df_base['Sex'] = df_base['Sex'].map({'male': 0,'female': 1})
如果仅存在女性
和男性
值,则解决方案将布尔掩码转换为整数真/假
转换为1,0
:
df_base['Sex'] = (df_base['Sex'] == 'female').astype(int)
性能:
np.random.seed(2019)
import perfplot
def ma(df):
df = df.copy()
df['Sex_new'] = df['Sex'].map({'male': 0,'female': 1})
return df
def rep1(df):
df = df.copy()
df['Sex'] = df['Sex'].replace(['male','female'],[0,1])
return df
def nwhere(df):
df = df.copy()
df['Sex_new'] = np.where(df['Sex'] == 'male', 0, 1)
return df
def mask1(df):
df = df.copy()
df['Sex_new'] = (df['Sex'] == 'female').astype(int)
return df
def mask2(df):
df = df.copy()
df['Sex_new'] = (df['Sex'].values == 'female').astype(int)
return df
def make_df(n):
df = pd.DataFrame({'Sex': np.random.choice(['male','female'], size=n)})
return df
结论:
如果仅替换2个值是最慢的replace
,numpy.where、map和mask
。要提高性能,请将numpy数组与值进行比较
也取决于数据,因此最好使用真实数据进行测试。另一种解决方案可以与np一起使用。其中
:
只是一个示例数据帧:
>>> df
Sex
0 male
1 female
2 female
3 female
4 male
>>> df['new_Sex'] = np.where(df['Sex'] != 'male', 1, 0)
>>> df
Sex new_Sex
0 male 0
1 female 1
2 female 1
3 female 1
4 male 0
根据条件创建新列new\u Sex
>>> df['new_Sex'] = np.where(df['Sex'] == 'male', 0, 1)
>>> df
Sex new_Sex
0 male 0
1 female 1
2 female 1
3 female 1
4 male 0
或:
>>> df
Sex
0 male
1 female
2 female
3 female
4 male
>>> df['new_Sex'] = np.where(df['Sex'] != 'male', 1, 0)
>>> df
Sex new_Sex
0 male 0
1 female 1
2 female 1
3 female 1
4 male 0
可与np一起使用的另一种解决方案。其中
:
只是一个示例数据帧:
>>> df
Sex
0 male
1 female
2 female
3 female
4 male
>>> df['new_Sex'] = np.where(df['Sex'] != 'male', 1, 0)
>>> df
Sex new_Sex
0 male 0
1 female 1
2 female 1
3 female 1
4 male 0
根据条件创建新列new\u Sex
>>> df['new_Sex'] = np.where(df['Sex'] == 'male', 0, 1)
>>> df
Sex new_Sex
0 male 0
1 female 1
2 female 1
3 female 1
4 male 0
或:
>>> df
Sex
0 male
1 female
2 female
3 female
4 male
>>> df['new_Sex'] = np.where(df['Sex'] != 'male', 1, 0)
>>> df
Sex new_Sex
0 male 0
1 female 1
2 female 1
3 female 1
4 male 0
我的直觉可能会建议使用.map()
,但我基于一个包含1500个随机男性/女性值的数据框,将您的解决方案与map进行了比较
%timeit df_base['Sex_new'] = df_base['Sex'].map({'male': 0,'female': 1})
1000 loops, best of 3: 653 µs per loop
根据coldspeeds注释进行编辑,因为重新指定它与其他注释相比更好:
%timeit df_base['Sex_new'] = df_base['Sex'].replace(['male','female'],[0,1])
1000 loops, best of 3: 968 µs per loop
所以实际上要慢一点.map()
因此,基于此示例,您的“劣质”解决方案似乎比.map()
编辑
pygo的解决方案:
%timeit df_base['Sex_new'] = np.where(df_base['Sex'] == 'male', 0, 1)
1000 loops, best of 3: 331 µs per loop
太快了
Jezrael的解决方案具有.astype(int)
:
因此也比.map()
和.replace()
更快 我的直觉会建议使用.map()
,但我基于一个包含1500个随机男性/女性值的数据框,对您的解决方案和map进行了比较
%timeit df_base['Sex_new'] = df_base['Sex'].map({'male': 0,'female': 1})
1000 loops, best of 3: 653 µs per loop
根据coldspeeds注释进行编辑,因为重新指定它与其他注释相比更好:
%timeit df_base['Sex_new'] = df_base['Sex'].replace(['male','female'],[0,1])
1000 loops, best of 3: 968 µs per loop
所以实际上要慢一点.map()
因此,基于此示例,您的“劣质”解决方案似乎比.map()
编辑
pygo的解决方案:
%timeit df_base['Sex_new'] = np.where(df_base['Sex'] == 'male', 0, 1)
1000 loops, best of 3: 331 µs per loop
太快了
Jezrael的解决方案具有.astype(int)
:
因此也比.map()
和.replace()
更快 为什么我看不到有人建议重复,而问题实际上是重复的?@coldspeed,我从未了解过这条线索,所以不能将其作为重复播放。@pygo我不反对有人建议重复,但我不喜欢双重标准。我在任何地方都能看到它,而且对某些用户来说比其他用户要多。@coldspeed-是的,标准解决方案是replace/map,但如果OP需要性能,还有其他解决方案,所以不会被我愚弄。@jezrael每个问题都可以用这种推理来解决。我相信你以前也用过同样的推理来回答类似的问题,所以找一个,并标记为dupe。或者向复制目标添加答案。这样你会比一遍又一遍地回答这样的问题得到更多的支持。为什么我看不到有人建议重复,而这个问题实际上是重复的?@coldspeed,我从来都不知道这个帖子,所以不能将它作为重复播放。@pygo我不反对有人建议重复,但我不喜欢双重标准。我在任何地方都能看到它,而且对某些用户来说比其他用户要多。@coldspeed-是的,标准解决方案是replace/map,但如果OP需要性能,还有其他解决方案,所以不会被我愚弄。@jezrael每个问题都可以用这种推理来解决。我相信你以前也用过同样的推理来回答类似的问题,所以找一个,并标记为dupe。或者向复制目标添加答案。通过这种方式,你将获得更多的代表性,而不是一遍又一遍地回答这样的问题。关于df['Old_Sex']=np.where(df['Sex']='male',0,1)
comparations?并检查map/replace
comparisonYes,使用numpy的解决方案将更快。注意df_base['Sex'].replace(['male','female',',',',0,1],inplace=True)
将不起作用,因为带有replace的系列上的inplace=True
有问题的历史记录。重新分配。感谢您的计时,但我还有其他问题,replace
对我来说比较慢,请检查我的答案。您测试性能的代码是什么?关于df['Old_Sex']=np。其中(df['Sex']='male',0,1)
比较?并检查<