【问题标题】:Error when using pandas dataframe map function in ipython notebook在 ipython 笔记本中使用 pandas 数据帧映射函数时出错
【发布时间】:2015-07-29 05:29:08
【问题描述】:

我刚开始使用 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")

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

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

...成功,Gender 列追加到末尾,女性为 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 值。我猜这是一个菜鸟问题:)

【问题讨论】:

  • 我认为你不需要那些astype(int)s,顺便说一句。
  • 有些东西没有加起来你的性别有 891 行 value_counts 但你的出发有 889 行,这意味着你必须有 NaN 值,docs 声明 NaN 值如果您尝试df['Embarked'].value_counts(dropna=False),您可以确认这一点,这意味着您需要通过在调用 map 之前先填充它们来处理 NaN
  • 报错信息的最后一行:ValueError: Cannot convert NA to integer。您可能必须从数据框中删除 NA。
  • 关于多余的 .astype(int),我觉得它在那里很奇怪。从 Kaggle 的教程中复制的。感谢您的澄清! @阿米

标签: python pandas ipython-notebook


【解决方案1】:

默认情况下 value_counts 不计算 NaN 值,您可以通过 df['Embarked'].value_counts(dropna=False) 更改此值。

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

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

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

【讨论】:

  • 我不知道value_counts() 默认删除了 NaN 值。添加了此命令 df2=df2.dropna(subset=['Embarked']) 并删除了 NaN,但是现在尝试运行 map 命令时出现不同的错误:` C:\Anaconda\lib\site-packages\IPython\kernel_main_ .py:1:SettingWithCopyWarning:试图在数据帧的切片副本上设置一个值。尝试改用 .loc[row_indexer,col_indexer] = value`
  • 您会收到该警告,因为 df2 是您原始 df 的副本,因为这一行:df2 = df[ ['Survived', 'Pclass', 'Age', 'Gender', 'Embarked'] ] 所以您需要在获取副本之前进行 Embarked 映射
  • 我在运行df['Embarked_int'] = df['Embarked'].map( {'S': 0, 'C': 1, 'Q': 2}) 时没有遇到同样的错误(谢谢)。为什么 iPython 关心我是针对副本还是针对原始命令运行命令?我会假设没有联系......
  • 进一步考虑这一点,如果我想拥有一个包含不同列的单独数据框,我最好重新导入数据并与新数据框关联,而不是复制一个子集的数据。
  • 发出警告以警告您,以防您的意图是您的操作应该在 orig df 上执行。如果您这样做了df2=df[ ['Survived', 'Pclass', 'Age', 'Gender', 'Embarked'] ].copy(),则不会发出警告,您无需再次加载数据。
【解决方案2】:

我刚刚在同一个数据集上遇到了这个问题。删除 'astype.int' 解决了整个问题。

【讨论】:

    猜你喜欢
    • 2016-02-22
    • 2016-09-06
    • 2017-01-25
    • 1970-01-01
    • 2015-09-21
    • 2014-02-08
    • 1970-01-01
    • 2016-05-26
    • 1970-01-01
    相关资源
    最近更新 更多