我要使用Apply来动态修改我的数据框的内容,该表就像:
Client.shared.reactions(forActivityId: state.activity.id, extraDataTypeOf: ReactionExtraData.self, userTypeOf: User.self) { [weak self](result) in
DispatchQueue.main.async {
self.state.connectionStatus = .ready
if let value = try? result.get() {
TempLogger.log("\(value.reactions.count)")
}
}
}
我的代码是:
index price signal stoploss
0 0 1000 True 990.0
1 1 1010 False 990.0
2 2 1020 True 1010.0
3 3 1000 False 1010.0
4 4 990 False 1010.0
5 5 980 False 1010.0
6 6 1000 False 1010.0
7 7 1020 True 1010.0
8 8 1030 False 1010.0
9 9 1040 False 1010.0
当我进入功能测试时,可以看到该值确实更改为1,但是超出功能测试范围,似乎对数据框没有影响。
我尝试使用另一种方式来修改数据框的内容,
def test(row, dd):
if row.signal:
dd['inorder']=True
row['stoploss']=1
df = pd.DataFrame({'index':[0,1,2,3,4,5,6,7,8,9],
'price':[1000,1010,1020,1000,990,980,1000,1020,1030,1040],
'signal':[True, False, True, False, False, False, False, True, False, False]})
if __name__ == '__main__':
df['stoploss'] = df.loc[df['signal'], 'price'] - 10
df['stoploss'].ffill(inplace=True)
xx = dict(inorder=False)
df.apply(lambda row: test(row, xx), axis=1)
print(df)
这是可行的,但是显然比应用慢得多。
我期望的正确结果是:
for k, row in df.iterrows():
if row.signal:
xx['inorder'] = True
df.loc[k, 'stoploss'] = 1
请问如何在申请中完成该任务?
谢谢
答案 0 :(得分:0)
如果查看apply
的文档,您会注意到apply
不会更改DataFrame的位置,而是返回已应用该功能的新数据框。
因此,在几秒钟到最后一行,您可以尝试
df = df.apply(lambda row: test(row, xx), axis=1)
编辑:
IMO,这没有很好的记录,但是电话
df.apply(func, axis=1)
将func
应用于每一行,并将行设置为返回值func
。
按照书面规定,您的示例将无法运行,因为您正在应用的函数不会返回任何内容。以下最小示例按照您的预期方式工作。
df = pd.DataFrame({'index':[0,1,2,3,4,5,6,7,8,9],
'price':[1000,1010,1020,1000,990,980,1000,1020,1030,1040],
'signal':[True, False, True, False, False, False, False, True, False, False]})
df['stoploss'] = df.loc[df['signal'], 'price'] - 10
df['stoploss'].ffill(inplace=True)
def test(row):
row.stoploss = 1 if row.signal else row.stoploss
return row
modified_df = df.apply(test, axis=1)
顺便说一句,我认为您实际上并不需要使用apply
来获得所需的结果。您是否尝试过类似的
df.loc[df['signal'] == True, 'stoploss'] = 1
这将是获得目标输出的更简单,更快捷的方法。