为了账号安全,请及时绑定邮箱和手机立即绑定

Pandas 将函数应用于列

Pandas 将函数应用于列

海绵宝宝撒 2023-06-27 17:32:16
我在将多个函数应用于我的数据框时遇到一些问题。我创建了一个示例代码来说明我正在尝试做什么。可能有比我正在做的方式更好的方法来完成这个特定的功能,但我试图为我的问题找到一个通用的解决方案,因为我使用了多个函数,而不仅仅是如何最有效地完成这个特定的事情。基本上,我有一个如下所示的示例数据框(df1):   Ticker      Date  High  Volume0    AAPL  20200501   1.5     1501    AAPL  20200501   1.2     1002    AAPL  20200501   1.3     1503    AAPL  20200502   1.4     1304    AAPL  20200502   1.2     1705    AAPL  20200502   1.1     1606    TSLA  20200501   2.5     2507    TSLA  20200501   2.2     2008    TSLA  20200501   2.3     2509    TSLA  20200502   2.4     23010   TSLA  20200502   2.2     27011   TSLA  20200502   2.1     260和一个如下所示的示例数据框(df2):  Ticker      Date  Price  SumVol0   AAPL  20200508    1.2       01   TSLA  20200508    2.2       0df2 中“SumVol”列中的值应填充 df1 中“Volume”列中值的总和,直到第一次在 df2 中看到“Price”(df1) 列中的值为止,并且df1 中的日期与 df2 中的日期匹配期望的输出:    Ticker      Date  Price  SumVol0   AAPL  20200508    1.2    3001   TSLA  20200508    2.2    500由于某种原因,我无法获得此输出,因为我可能在尝试将该函数应用于数据帧的代码行中做错了什么。我希望这里有人可以帮助我。完整的示例代码,包括示例数据帧:import pandas as pddf1 = pd.DataFrame({'Ticker': ['AAPL', 'AAPL', 'AAPL', 'AAPL', 'AAPL', 'AAPL', 'TSLA', 'TSLA', 'TSLA', 'TSLA', 'TSLA', 'TSLA'],                'Date': [20200501, 20200501, 20200501, 20200502, 20200502, 20200502, 20200501, 20200501, 20200501, 20200502, 20200502, 20200502],               'High': [1.5, 1.2, 1.3, 1.4, 1.2, 1.1, 2.5, 2.2, 2.3, 2.4, 2.2, 2.1],                'Volume': [150, 100, 150, 130, 170, 160, 250, 200, 250, 230, 270, 260]})print(df1)df2 = pd.DataFrame({'Ticker': ['AAPL', 'TSLA'],               'Date': [20200501, 20200502],                'Price': [1.4, 2.2],                'SumVol': [0,0]})print(df2)def VolSum(ticker, date, price):    df11 = pd.DataFrame(df1)    df11 = df11[df11['Ticker'] == ticker]    df11 = df11[df11['Date'] == date]    df11 = df11[df11['High'] < price]    df11 = pd.DataFrame(df11)    return df11.Volume.sumdf2['SumVol'].apply(VolSum(df2['Ticker'], df2['Date'], df2['Price']), inplace=True).reset_index(drop=True, inplace=True)print(df2)
查看完整描述

1 回答

?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

失败的第一个原因是你的函数以 return df11.Volume.sum(不带括号)结尾,因此你只返回sum函数,而不是其执行结果。

另一个原因是您可以将函数应用于 Dataframe 的每一行,但必须传递axis=1参数。但是之后:

  • 要应用的函数应该有一个参数 - 当前行,

  • 其结果可以替换到所需的列下。

失败的第三个原因是df2包含df1中不存在的日期,因此您不可能找到任何匹配的行。

如何获得预期结果 - 方法1

首先,df2必须包含可能与df1匹配的值。我将df2定义为:

  Ticker      Date  Price  SumVol

0   AAPL  20200501    1.4       0

1   TSLA  20200502    2.3       0

然后我将你的功能更改为:


def VolSum(row):

    df11 = pd.DataFrame(df1)

    df11 = df11[df11['Ticker'] == row.Ticker]

    df11 = df11[df11['Date'] == row.Date]

    df11 = df11[df11['High'] < row.Price]

    return df11.Volume.sum()

最后我生成的结果为:


df2['SumVol'] = df2.apply(VolSum, axis=1)

结果是:


  Ticker      Date  Price  SumVol

0   AAPL  20200501    1.4     250

1   TSLA  20200502    2.3     530

如何获得预期结果——方法2

但更简洁优雅的方法是将求和函数定义为:


def VolSum2(row):

    return df1.query('Ticker == @row.Ticker and '

        'Date == @row.Date and High < @row.Price').Volume.sum()

并以同样的方式应用它:


df2['SumVol'] = df2.apply(VolSum2, axis=1)

结果当然是一样的。


查看完整回答
反对 回复 2023-06-27
  • 1 回答
  • 0 关注
  • 100 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信