在将多个函数应用于数据框时,我遇到了一些问题。
我创建了一个示例代码来说明我正在尝试做的事情。可能比我执行此功能更好的方法来执行此特定功能,但是由于我正在使用多个功能,而不仅仅是如何最有效地执行此特定操作,因此我试图为我的问题找到一个通用的解决方案
基本上,我有一个示例数据框,看起来像这样(df1):
Ticker Date High Volume
0 AAPL 20200501 1.5 150
1 AAPL 20200501 1.2 100
2 AAPL 20200501 1.3 150
3 AAPL 20200502 1.4 130
4 AAPL 20200502 1.2 170
5 AAPL 20200502 1.1 160
6 TSLA 20200501 2.5 250
7 TSLA 20200501 2.2 200
8 TSLA 20200501 2.3 250
9 TSLA 20200502 2.4 230
10 TSLA 20200502 2.2 270
11 TSLA 20200502 2.1 260
和一个看起来像这样的示例数据框(df2):
Ticker Date Price SumVol
0 AAPL 20200508 1.2 0
1 TSLA 20200508 2.2 0
df2中“ SumVol”列中的值应填充df1中“ Volume”列中的值之和,直到第一次在“ Price”(df1)列中看到该值df2,并且df1中的日期与df2中的日期匹配
所需的输出:
Ticker Date Price SumVol
0 AAPL 20200508 1.2 300
1 TSLA 20200508 2.2 500
由于某种原因,我无法获得此输出,因为我可能在试图将函数应用于数据框的代码行中做错了什么。我希望这里有人可以帮助我。
完整的示例代码,包括示例数据帧:
import pandas as pd
df1 = 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.sum
df2['SumVol'].apply(VolSum(df2['Ticker'], df2['Date'], df2['Price']), inplace=True).reset_index(drop=True, inplace=True)
print(df2)
答案 0 :(得分:1)
失败的第一个原因是您的功能以
return df11.Volume.sum
(无括号),
因此您只返回 sum 函数,而不是执行结果。
另一个原因是您可以将函数应用于数据框的每一行, 但是您必须传递 axis = 1 参数。但是然后:
失败的第三个原因是 df2 包含例如日期不存在 在 df1 中,因此您不太可能找到任何匹配的行。
首先, 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
但是更简洁,优雅的方法是将求和函数定义为:
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)
结果当然是一样的。