在具有 lambda 函数的数据框中使用 if 语句

Using an if statement in a dataframe with lambda functions

我正在尝试根据两列的值根据 if 语句向数据框添加新列。即如果列 x == 无则列 y 否则列 x

下面是我写的脚本,但不起作用。有什么想法吗?

dfCurrentReportResults['Retention'] =  dfCurrentReportResults.apply(lambda x : x.Retention_y if x.Retention_x == None else x.Retention_x)

我也收到了这个错误信息: AttributeError: ("'Series' object has no attribute 'Retention_x'", u'occurred at index BUSINESSUNIT_NAME')

仅供参考:BUSINESSUNIT_NAME是第一列名称

附加信息:

我的数据打印出来是这样的,我想添加第 3 列来取一个值,如果还有一个保留 NaN。

   Retention_x  Retention_y
0            1          NaN
1          NaN     0.672183
2          NaN     1.035613
3          NaN     0.771469
4          NaN     0.916667
5          NaN          NaN
6          NaN          NaN
7          NaN          NaN
8          NaN          NaN
9          NaN          NaN

更新: 最后,我遇到了在我的数据框中引用 Null 或 is Null 的问题,我使用的最后一行代码还包括 axis = 1 回答了我的问题。

 dfCurrentReportResults['RetentionLambda'] = dfCurrentReportResults.apply(lambda x : x['Retention_y'] if pd.isnull(x['Retention_x']) else x['Retention_x'], axis = 1)

感谢@EdChum、@strim099 和@aus_lacy 提供的所有信息。随着我的数据集变大,如果我发现性能问题,我可能会切换到 np.where 选项。

只需使用np.where:

dfCurrentReportResults['Retention'] =  np.where(df.Retention_x == None, df.Retention_y, else df.Retention_x)

这使用测试条件,第一个参数并将值设置为 df.Retention_y else df.Retention_x

还应尽可能避免使用 apply,因为这只会遍历值,np.where 是一种矢量化方法,可扩展性更好。

更新

好的,不需要使用 np.where 只需使用以下更简单的语法:

dfCurrentReportResults['Retention'] =  df.Retention_y.where(df.Retention_x == None, df.Retention_x)

进一步更新

dfCurrentReportResults['Retention'] =  df.Retention_y.where(df.Retention_x.isnull(), df.Retention_x)

你的 lambda 在 0 轴上运行,它是按列排列的。只需将 axis=1 添加到 apply arg 列表。这有明确的记录。

In [1]: import pandas

In [2]: dfCurrentReportResults = pandas.DataFrame([['a','b'],['c','d'],['e','f'],['g','h'],['i','j']], columns=['Retention_y', 'Retention_x'])

In [3]: dfCurrentReportResults['Retention_x'][1] = None

In [4]: dfCurrentReportResults['Retention_x'][3] = None

In [5]: dfCurrentReportResults
Out[5]:
  Retention_y Retention_x
0           a           b
1           c        None
2           e           f
3           g        None
4           i           j

In [6]: dfCurrentReportResults['Retention'] =  dfCurrentReportResults.apply(lambda x : x.Retention_y if x.Retention_x == None else x.Retention_x, axis=1)

In [7]: dfCurrentReportResults
Out[7]:
  Retention_y Retention_x Retention
0           a           b         b
1           c        None         c
2           e           f         f
3           g        None         g
4           i           j         j