【问题标题】:Pandas Lambda Function with Nan Support支持 Nan 的 Pandas Lambda 函数
【发布时间】:2017-10-19 02:03:24
【问题描述】:

我正在尝试在 Pandas 中编写一个 lambda 函数来检查 Col1 是否为 Nan,如果是,则使用另一列的数据。我无法让代码(如下)正确编译/执行。

import pandas as pd
import numpy as np
df=pd.DataFrame({ 'Col1' : [1,2,3,np.NaN], 'Col2': [7, 8, 9, 10]})  
df2=df.apply(lambda x: x['Col2'] if x['Col1'].isnull() else x['Col1'], axis=1)

有没有人知道如何使用 lambda 函数编写这样的解决方案,或者我是否超出了 lambda 的能力?如果没有,您有其他解决方案吗?谢谢。

【问题讨论】:

  • 您的示例只有一列。如果您的数据集中没有Col2,则无法从Col2 中绘制;此外,一般来说,如果没有任何其他列,您将无法获得“另一列的数据”。
  • @aryamccarthy 道歉。我应该制作一个任意的“Col2”。我会测试并回来。
  • 这似乎不适用于我的大型 DataFrame,但在示例中确实有效。这可能是因为在我的实际数据集中有不同的数据类型,所以 fillna 无法正常工作?我的实际集合中的 Col1 和 Col2 都是 dtype('O') 所以这应该不是问题。

标签: python python-3.x pandas lambda nan


【解决方案1】:

假设您确实有第二列,即:

df = pd.DataFrame({ 'Col1' : [1,2,3,np.NaN], 'Col2': [1,2,3,4]})

这个问题的正确解决方案是:

df['Col1'].fillna(df['Col2'], inplace=True)

【讨论】:

  • 道歉。我应该制作一个任意的“Col2”。我会测试并回来。
  • 这似乎不适用于我的大型 DataFrame,但在示例中确实有效。这可能是因为在我的实际数据集中有不同的数据类型,所以 fillna 无法正常工作?我的实际集合中的 Col1 和 Col2 都是 dtype('O') 所以这应该不是问题。
  • 对象数据类型也适用于我。使用实际数据集有什么问题?
【解决方案2】:

你需要使用 np.nan()

#import numpy as np
df2=df.apply(lambda x: 2 if np.isnan(x['Col1']) else 1, axis=1)   

df2
Out[1307]: 
0    1
1    1
2    1
3    2
dtype: int64

【讨论】:

    【解决方案3】:

    您需要pandas.isnull 来检查标量是否为NaN

    df = pd.DataFrame({ 'Col1' : [1,2,3,np.NaN],
                     'Col2' : [8,9,7,10]})  
    
    df2 = df.apply(lambda x: x['Col2'] if pd.isnull(x['Col1']) else x['Col1'], axis=1)
    
    print (df)
       Col1  Col2
    0   1.0     8
    1   2.0     9
    2   3.0     7
    3   NaN    10
    
    print (df2)
    0     1.0
    1     2.0
    2     3.0
    3    10.0
    dtype: float64
    

    但更好的是使用Series.combine_first:

    df['Col1'] = df['Col1'].combine_first(df['Col2'])
    
    print (df)
       Col1  Col2
    0   1.0     8
    1   2.0     9
    2   3.0     7
    3  10.0    10
    

    Series.update 的另一种解决方案:

    df['Col1'].update(df['Col2'])
    print (df)
       Col1  Col2
    0   8.0     8
    1   9.0     9
    2   7.0     7
    3  10.0    10
    

    【讨论】:

    • 谢谢。你的意思是你的 else 在你的第一个 lambda 方法中是 Col1 还是 Col2?
    • 嗯,我认为是Col2 - 这意味着如果条件为真,则获取 col2 的值,否则获取 col1 的值
    • 但如果需要将 NaNs 替换为另一列,我更喜欢其他解决方案。
    • 您的前两种方法完美无缺。只是出于好奇,您为什么认为在 df 上使用 Series.combine_first 而不是 lambda 函数更好?
    • 因为它是更快的矢量化函数。但是如果数据框很小(100行),那没问题。但如果1M 行,则存在巨大差异。
    【解决方案4】:

    在 pandas 0.24.2 中,我使用

    df.apply(lambda x: x['col_name'] if x[col1] is np.nan else expressions_another, axis=1)
    

    因为 pd.isnull() 不起作用。

    在我的工作中,我发现了以下现象,

    没有运行结果:

    df['prop'] = df.apply(lambda x: (x['buynumpday'] / x['cnumpday']) if pd.isnull(x['cnumpday']) else np.nan, axis=1)
    

    结果存在:

    df['prop'] = df.apply(lambda x: (x['buynumpday'] / x['cnumpday']) if x['cnumpday'] is not np.nan else np.nan, axis=1)
    

    到目前为止,我仍然不知道更深层次的原因,但我有这些经验,对于对象,使用[is np.nan()]或pd.isna()。对于浮点数,使用 np.isnan() 或 pd.isna()。

    【讨论】:

      猜你喜欢
      • 2017-10-23
      • 1970-01-01
      • 2013-08-11
      • 2020-08-26
      • 2019-01-06
      • 2020-08-30
      • 2018-01-17
      • 2015-07-09
      • 1970-01-01
      相关资源
      最近更新 更多