Skip to main content
 首页 » 编程设计

python之在 ipython notebook 中使用 pandas dataframe map 函数时出错

2025年05月04日22mengfanrong

我刚开始使用 Python,在处理 Kaggle Titanic 数据时遇到了一些问题。 https://www.kaggle.com/c/titanic/data

这是我在 ipython 笔记本中输入的内容(train.csv 来自上面 kaggle 链接的泰坦尼克号数据):

import pandas as pd 
df = pd.read_csv("C:/fakepath/titanic/data/train.csv") 

然后我继续检查“性别”列中是否有任何错误数据:

df['Sex'].value_counts() 

哪个返回:

male      577 
 
female    314 
 
dtype: int64 
df['Gender'] = df['Sex'].map( {'male': 1, 'female': 0} ).astype(int) 

这不会产生任何错误。要验证它是否创建了一个名为“性别”且具有整数值的新列:

df 

返回:

#    PassengerId    Survived    Pclass  Name    Sex Age SibSp   Parch   Ticket  Fare    Cabin   Embarked    Gender 
    0   1   0   3   Braund, Mr. Owen Harris male    22  1   0   A/5 21171   7.2500  NaN S   1 
    1   2   1   1   Cumings, Mrs. John Bradley (Florence Briggs Th...   female  38  1   0   PC 17599    71.2833 C85 C   0 
    2   3   1   3   Heikkinen, Miss. Laina  female  26  0   0   STON/O2. 3101282    7.9250  NaN S   0 
    3   4   1   1   Futrelle, Mrs. Jacques Heath (Lily May Peel)    female  35  1   0   113803  53.1000 C123    S   0 

...成功,性别列附加到末尾,0 代表女性,1 代表男性。现在,我创建了一个新的 pandas 数据框,它是 df 数据框的一个子集。

df2 = df[ ['Survived', 'Pclass', 'Age', 'Gender', 'Embarked'] ] 
df2 

返回:

    Survived    Pclass  Age Gender  Embarked 
0   0   3   22  1   S 
1   1   1   38  0   C 
2   1   3   26  0   S 
3   1   1   35  0   S 
4   0   3   35  1   S 
5   0   3   NaN 1   Q 
df2['Embarked'].value_counts() 

...显示有 3 个唯一值(S、C、Q):

S    644 
C    168 
Q     77 
dtype: int64 

但是,当我尝试执行我认为与将男/女转换为 1/0 时相同类型的操作时,出现错误:

df2['Embarked_int'] = df2['Embarked'].map( {'S': 0, 'C': 1, 'Q': 2}).astype(int) 

返回:

    ValueError                                Traceback (most recent call last) 
<ipython-input-29-294c08f2fc80> in <module>() 
----> 1 df2['Embarked_int'] = df2['Embarked'].map( {'S': 0, 'C': 1, 'Q': 2}).astype(int) 
 
C:\Anaconda\lib\site-packages\pandas\core\generic.pyc in astype(self, dtype, copy, raise_on_error) 
   2212  
   2213         mgr = self._data.astype( 
-> 2214             dtype=dtype, copy=copy, raise_on_error=raise_on_error) 
   2215         return self._constructor(mgr).__finalize__(self) 
   2216  
 
C:\Anaconda\lib\site-packages\pandas\core\internals.pyc in astype(self, dtype, **kwargs) 
   2500  
   2501     def astype(self, dtype, **kwargs): 
-> 2502         return self.apply('astype', dtype=dtype, **kwargs) 
   2503  
   2504     def convert(self, **kwargs): 
 
C:\Anaconda\lib\site-packages\pandas\core\internals.pyc in apply(self, f, axes, filter, do_integrity_check, **kwargs) 
   2455                                                  copy=align_copy) 
   2456  
-> 2457             applied = getattr(b, f)(**kwargs) 
   2458  
   2459             if isinstance(applied, list): 
 
C:\Anaconda\lib\site-packages\pandas\core\internals.pyc in astype(self, dtype, copy, raise_on_error, values) 
    369     def astype(self, dtype, copy=False, raise_on_error=True, values=None): 
    370         return self._astype(dtype, copy=copy, raise_on_error=raise_on_error, 
--> 371                             values=values) 
    372  
    373     def _astype(self, dtype, copy=False, raise_on_error=True, values=None, 
 
C:\Anaconda\lib\site-packages\pandas\core\internals.pyc in _astype(self, dtype, copy, raise_on_error, values, klass) 
    399             if values is None: 
    400                 # _astype_nansafe works fine with 1-d only 
--> 401                 values = com._astype_nansafe(self.values.ravel(), dtype, copy=True) 
    402                 values = values.reshape(self.values.shape) 
    403             newb = make_block(values, 
 
C:\Anaconda\lib\site-packages\pandas\core\common.pyc in _astype_nansafe(arr, dtype, copy) 
   2616  
   2617         if np.isnan(arr).any(): 
-> 2618             raise ValueError('Cannot convert NA to integer') 
   2619     elif arr.dtype == np.object_ and np.issubdtype(dtype.type, np.integer): 
   2620         # work around NumPy brokenness, #1987 
 
ValueError: Cannot convert NA to integer 

知道为什么我在第二次使用 map 函数时出现此错误,但在第一次使用时却没有吗?每个 value_counts() 的 Embarked 列中没有 NAN 值。我猜这是一个菜鸟问题:)

请您参考如下方法:

默认 value_counts不计算 NaN 值,您可以通过执行 df['Embarked'].value_counts(dropna=False) 来更改它。

我查看了性别列 (577 + 314 = 891) 与登船列 (644 + 168 + 77 = 889) 的 value_counts,它们相差 2,这意味着您必须有 2 NaN 值。

因此,您要么先删除它们(使用 dropna),要么使用 fillna 为它们填充一些所需的值。

astype(int) 也是多余的,因为您无论如何都映射到一个 int。