【问题标题】:DataFrame logic operations with NaN使用 NaN 的 DataFrame 逻辑操作
【发布时间】:2016-05-11 23:44:33
【问题描述】:

我正在尝试在 pandas DataFrame 中进行一些比较。

# create simple DataFrame
df = pd.DataFrame(['one', 'two', 'three'], range(1,4), columns=['col1'])
#df:
#    col1
#1    one
#2    two
#3  three

# assign one col1 value to be NAN
df.loc[1, 'col1'] = np.nan 
# this comparison works
print(df['col1'] == 'three')

# assign all col1 values to NAN
df.loc[:, 'col1'] = np.nan
# this comparison fails
print(df['col1'] == 'three')

第一个比较(列中只有一个 NAN 值)按预期工作,但第二个比较(列中所有 NAN 值)产生此错误:TypeError: invalid type comparison

这里发生了什么?

我看到了这个question,它为这个问题提出了一些可能但有点破解的解决方案。

但为什么会发生这种行为呢?不知何故,这个限制有用吗?我可以在比较之前使用df.fillna('') 来修复它,但这看起来很笨拙且令人恼火。

所以我的问题是:
1. 解决这个问题最干净的方法是什么?
2. 为什么这是默认行为?

【问题讨论】:

    标签: python numpy pandas


    【解决方案1】:

    您的col1 在分配所有np.nan 后属于float 类型,因此尝试与string 进行比较会抛出TypeError。 :

    df = pd.DataFrame(['one', 'two', 'three'], range(1, 4), columns=['col1'])
    df.loc[1, 'col1'] = np.nan
    
        col1
    1    NaN
    2    two
    3  three
    

    将单个np.nan 分配给包含string 值的列会留下dtype 对象:

    df.info()
    
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 3 entries, 1 to 3
    Data columns (total 1 columns):
    col1    2 non-null object
    dtypes: object(1)
    

    但所有np.nan 值都转换为float

    df.loc[:, 'col1'] = np.nan
    df.info()
    
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 3 entries, 1 to 3
    Data columns (total 1 columns):
    col1    0 non-null float64
    dtypes: float64(1)
    

    【讨论】:

    • 这就是答案
    • 谢谢——这真的很有帮助。我坚持我认为是 pandas 的标准,但这有助于我更好地理解类型问题。
    【解决方案2】:

    该问题可以通过使用ix 索引器而不是iloc 来解决,在这种情况下,系列的数据类型不会更改(不知道为什么会这样,大概这两种类型的索引器应该具有一致的行为,我的偏好是将iloc 更改为匹配ix):

    >>> df = pd.DataFrame(['one', 'two', 'three'], range(1,4), columns=['col1'])
    >>> df['col1'].ix[:] = np.nan
    >>> df.dtypes
    
    col1    object
    dtype: object
    

    【讨论】:

      【解决方案3】:

      如果你这样做了:

      # assign all col1 values to None
      df.loc[:, 'col1'] = None
      

      然后

      # this comparison does not fail
      print df['col1'] == 'three'
      
      1    False
      2    False
      3    False
      Name: col1, dtype: bool
      

      【讨论】:

        猜你喜欢
        • 2021-01-01
        • 1970-01-01
        • 2014-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多