【问题标题】:Apply function to column with null values and return NaN if null将函数应用于具有空值的列,如果为空则返回 NaN
【发布时间】:2019-12-15 21:07:41
【问题描述】:

我正在尝试将函数 convert_label() 应用于我的数据框的 CR_df['label'] 列。函数的输出存储在单独的列 CR_df['y'] 中。但是,我的 CR_df['label'] 列包含具有 NaN 值的单元格。我只想将我的函数应用于 CR_df['label'] 中没有 NaN 值的单元格。如果单元格确实有 NaN 值,我想在相应的 CR_df['y'] 单元格中返回 NaN。

我不想检查我是否有 NaN 值,如果是 NaN,我需要返回 NaN。

我的(容易出错的)解决方案尝试

def convert_label(label):
    if "pos" in label:
        output = 1.0
    elif "neg" in label:
        output = 0.0
    else:
        output = label
    return output

我尝试将 NaN 转换为字符串,然后应用我的函数,但现在我需要将 CR_df['y'] 中的所有字符串“nan”更改为实际的 NaN 或 null 值

CR_df['y'] = CR_df['label'].astype(str).apply(convert_label)

我附上了我的输出图片

另外,这是我的数据框的代码

    CR_train_file='data/custrev_train.tsv'
CR_test_file = 'data/custrev_test.tsv'


CR_train_df = pd.read_csv(CR_train_file, sep='\t', header=None)
CR_train_df.columns = ['index', 'label', 'review']
CR_test_df = pd.read_csv(CR_test_file, sep='\t', header=None)
CR_test_df.columns = ['index', 'review']
CR_test_df
CR_df = pd.concat([CR_train_df,CR_test_df], axis=0, ignore_index=True)

【问题讨论】:

  • 这能回答你的问题吗? How can I check for NaN values?
  • 不,它没有。我的问题是如何返回 NaN 值
  • 您可以为您的数据框添加一个示例吗?
  • 上面提供了数据框示例
  • 下次可以发布代码来生成这样的数据帧,而不是图片。

标签: python pandas


【解决方案1】:

您应该能够使用float 来分配带有NaN 的变量:

>>> import math
>>> a = float('nan')
>>> math.isnan(a)
True
>>> b = 'nan'
>>> math.isnan(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be real number, not str
>>> 

在上面,a 被分配了一个实际的 NaN 值,而 b 只有一个 'nan' 字符串

【讨论】:

  • 有没有办法做到这一点,而无需遍历我的数据框?另外,我如何直接应用函数并返回 NaN 而不必先将所有内容都转换为字符串?
  • @NingkaiZheng 第一个问题没有。至于第二个,项目不是已经是字符串了吗?
【解决方案2】:

与当前接受的答案不同,它出于某种原因使用 None,这确实满足条件 我不想检查我是否有 NaN 值,如果是 NaN,我需要返回 NaN。


嗯,我们将本质上是一个二进制变量(当然还有NaN)映射到0.01.0。在我看来,我们需要一些布尔值™。

df_1 = pd.DataFrame(data=[('646', 'pos', 'bla bla 1'), ('2910', 'neg', 'bla bla 2'),
                          ('49', np.NaN, 'bla bla 3')], columns=['index_num', 'label', 'review'])

# accessing columns like civilized beings
df_1['y'] = df_1['label'].map({'pos': True, 'neg': False})

之前:

  index_num label     review
0       646   pos  bla bla 1
1      2910   neg  bla bla 2
2        49   NaN  bla bla 3

之后:

  index_num label     review      y
0       646   pos  bla bla 1   True
1      2910   neg  bla bla 2  False
2        49   NaN  bla bla 3    NaN

即使假设我们要映射到0.01.0,仍然没有任何借口可以让apply() 具有完整的功能。

【讨论】:

    【解决方案3】:

    您可以修改您的函数,使其检查无。如果您不想这样做,您可以使用 lambda 函数在 apply 调用中检查 None(或 NaN,具体取决于您的需要)。

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame({'label': [1, np.NaN, 'neg',[2], 
                             3, 'pos', 5, None,
                             np:NaN, 'test']})
    
    def convert_label(label):
        if "pos" == label:
            return 1.0
        elif "neg" == label:
            return 0.0
        else:
            return label
    
    df.label.apply(lambda x: convert_label(x) if x is not np.NaN else np.NaN)
    >>>
    0       1
    1    None
    2       0
    3     [2]
    4       3
    5       1
    6       5
    7    None
    8    None
    9    test
    Name: label, dtype: object
    

    或者你使用DataFrame().where():

    df.label.where(~df.label.isnull(), lambda x: convert_label(x))
    

    【讨论】:

    • 当问题明确提到 NaN(Pandas 标准)时,为什么要使用 None
    • 可以改成NaN
    猜你喜欢
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 2020-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-25
    相关资源
    最近更新 更多