当前位置: 首页 > 知识库问答 >
问题:

如何对单个列使用apply()函数?

童宏富
2023-03-14

我有一个有两列的熊猫数据框。我需要在不影响第二列的情况下更改第一列的值,并在仅更改第一列值的情况下返回整个数据帧。我如何在熊猫身上使用apply?

共有3个答案

范凡
2023-03-14

给定以下数据框df和函数complex_function

  import pandas as pd

  def complex_function(x, y=0):
      if x > 5 and x > y:
          return 1
      else:
          return 2

  df = pd.DataFrame(data={'col1': [1, 4, 6, 2, 7], 'col2': [6, 7, 1, 2, 8]})
     col1  col2
  0     1     6
  1     4     7
  2     6     1
  3     2     2
  4     7     8

有几种解决方案可以仅在一个列上使用应用()。在下面我将详细解释它们。

直截了当的解决方案来自@Fabio Lamanna:

  df['col1'] = df['col1'].apply(complex_function)

输出:

     col1  col2
  0     2     6
  1     2     7
  2     1     1
  3     2     2
  4     1     8

仅修改第一列,第二列不变。这个解决方案很漂亮。它只是一行代码,读起来几乎像英语:“取'col1'并将函数complex_函数应用于它。”

但是,如果您需要来自另一列的数据,例如“col2”,它将不起作用。如果要将'col2'的值传递给复杂函数的变量y,则需要其他内容。

或者,您可以使用这个或这个SO帖子中描述的整个数据框:

  df['col1'] = df.apply(lambda x: complex_function(x['col1']), axis=1)

或者如果你喜欢(像我一样)没有lambda函数的解决方案:

  def apply_complex_function(x): return complex_function(x['col1'])
  df['col1'] = df.apply(apply_complex_function, axis=1) 

这个解决方案中有很多问题需要解释。函数的作用是:pd.Series和pd.DataFrame。但是不能使用df['col1']=df.apply(complex_function).loc[:,'col1'],因为它会抛出ValueError

因此,您需要给出要使用哪个列的信息。使事情复杂化的是,apply()函数只接受可调用项。要解决这个问题,您需要定义一个(lambda)函数,其中列x['col1']作为参数;i、 我们将列信息包装在另一个函数中。

不幸的是,axis参数的默认值为零(axis=0),这意味着它将尝试按列而不是按行执行。这在第一个解决方案中不是问题,因为我们给apply()一个pd.Series。但是现在输入是一个数据帧,我们必须是显式的(axis=1)。(我很惊讶我经常忘记这一点。)

您是否喜欢带有lambda函数的版本是主观的。在我看来,这一行代码足够复杂,即使没有插入lambda函数也能阅读。您只需要(lambda)函数作为包装器。这只是锅炉代码。读者不应该为此烦恼。

现在,您可以轻松修改此解决方案,以考虑第二列:

    def apply_complex_function(x): return complex_function(x['col1'], x['col2'])
    df['col1'] = df.apply(apply_complex_function, axis=1)

输出:

     col1  col2
  0     2     6
  1     2     7
  2     1     1
  3     2     2
  4     2     8

在索引4处,该值已从1更改为2,因为第一个条件7

请注意,您只需要更改第一行代码(即函数),而不需要更改第二行。

切勿将列信息放入函数中。

  def bad_idea(x):
      return x['col1'] ** 2

通过这样做,您可以创建一个依赖于列名称的通用函数!这是一个糟糕的主意,因为下次你想使用这个功能时,你不能。更糟糕的是:也许你在不同的数据框中重命名一列,只是为了让它与你现有的函数一起工作。(去过那里,做到了。这是一个滑坡!)

尽管OP特别要求使用apply()解决方案,但还是建议了其他解决方案。例如,@George Petrov的答案建议使用map(),而@Thibaut Dubernet的答案建议使用assign()。

我完全同意应用()很少是最好的解决方案,因为应用()没有矢量化。它是一种元素操作,具有昂贵的函数调用和pd开销。系列。

使用apply()的一个原因是您希望使用现有函数,而性能不是问题。或者您的函数非常复杂,不存在矢量化版本。

另一个使用应用()的原因是与Groupby()结合使用。请注意,DataFrame.apply()和GroupBy.apply()是不同的函数。

所以考虑一些替代方案是有意义的:

  • map()仅适用于pd.Series,但接受dict和pd.Series作为输入。在函数中使用map()与使用apply()几乎可以互换。它可以比apply()更快。有关更多详细信息,请参阅此SO帖子
  df['col1'] = df['col1'].map(complex_function)
  • applymap()对于数据帧几乎相同。它不支持pd.Series,它将始终返回数据帧。但是,它可以更快。文档中说:“在当前的实现中,applymap在第一列/行上调用func两次,以决定它可以采用快速还是慢速代码路径。”。但如果性能真的很重要,你应该寻找一条替代路线
  df['col1'] = df.applymap(complex_function).loc[:, 'col1']
  • assign()不能替代apply()。它仅在最基本的用例中具有类似的行为。它不适用于复杂函数。您仍然需要apply(),如下面的示例所示。assign()的主要用例是方法链接,因为它返回数据帧而不更改原始数据帧
  df['col1'] = df.assign(col1=df.col1.apply(complex_function))

我在这里提到这一点,是因为其他答案,例如@durjoy,都提出了这一点。清单并非详尽无遗:

  1. 不要使用apply()。这不是开玩笑。对于大多数数值操作,熊猫中存在向量化方法。If/else块通常可以通过布尔索引和.loc组合进行重构。我的示例复杂函数可以用这种方式重构。

周鸿光
2023-03-14

对于单个列,最好使用map(),如下所示:

df = pd.DataFrame([{'a': 15, 'b': 15, 'c': 5}, {'a': 20, 'b': 10, 'c': 7}, {'a': 25, 'b': 30, 'c': 9}])

    a   b  c
0  15  15  5
1  20  10  7
2  25  30  9



df['a'] = df['a'].map(lambda a: a / 2.)

      a   b  c
0   7.5  15  5
1  10.0  10  7
2  12.5  30  9
施靖
2023-03-14

给定一个示例数据帧df,如下所示:

a,b
1,2
2,3
3,4
4,5

你想要的是:

df['a'] = df['a'].apply(lambda x: x + 1)

返回:

   a  b
0  2  2
1  3  3
2  4  4
3  5  5
 类似资料:
  • 问题内容: 我有两列的熊猫数据框。我需要在不影响第二列的情况下更改第一列的值,并只更改第一列的值即可获取整个数据帧。如何使用大熊猫应用程序? 问题答案: 给定一个示例数据框为: 您想要的是: 返回:

  • 考虑这个例子 我有一个函数,它以作为输入,并返回三个值,我想存储到三个不同的变量。下面的似乎工作正确 然而,当我试图创建相应的变量时,我得到了一个错误 你怎么认为? 我曾经在pandas apply()的返回多列中使用伟大的解决方案,但在当前的pandas中,此解决方案不再有效 谢谢!

  • 本文向大家介绍Pandas对每个分组应用apply函数的实现,包括了Pandas对每个分组应用apply函数的实现的使用技巧和注意事项,需要的朋友参考一下 Pandas的apply函数概念(图解) 实例1:怎样对数值按分组的归一化 实例2:怎样取每个分组的TOPN数据 到此这篇关于Pandas对每个分组应用apply函数的实现的文章就介绍到这了,更多相关Pandas 应用apply函数内容请搜索呐

  • 我有一个数据框,如: 我需要为每个列应用一些函数,并在这个数据帧中创建具有特殊名称的新列。 所以我需要根据列和(如name)乘以两个额外的列,名称为和由两个。是否可以使用或其他结构来完成此操作?

  • 本文向大家介绍对pandas中apply函数的用法详解,包括了对pandas中apply函数的用法详解的使用技巧和注意事项,需要的朋友参考一下 最近在使用apply函数,总结一下用法。 apply函数可以对DataFrame对象进行操作,既可以作用于一行或者一列的元素,也可以作用于单个元素。 例:列元素 行元素 列 行 以上这篇对pandas中apply函数的用法详解就是小编分享给大家的全部内容了

  • 我有2个微服务:我们称它们为A和B。 由B处理的实体(其中引用了a的实体)被实现为简单的长id(例如groupId) 我想要实现的是使用mapstruct填充B(由A持有)的缺失组数据。到目前为止,我尝试使用@AfterMapping函数向a请求缺失的数据。我的映射器是: 给我映射功能的实现接口是: 生成的代码的问题在于,将实体列表映射到DTO列表的函数对每个实体使用EntityToToTo,导致