添加条件下的值到新列 Pandas

huangapple go评论94阅读模式
英文:

Add values to new column Pandas with condition

问题

  1. if self.dataframe['Symbol'].isin(['CAD', 'EUR']).any():
  2. self.dataframe['PnL_Profit'] = round((self.dataframe['Entry'] - self.dataframe['TP']) * (self.dataframe['LOTS'] * 100000) / self.dataframe['TP'], 2)
  3. elif self.dataframe['Symbol'].eq('XAU').any():
  4. self.dataframe['PnL_Profit'] = round((self.dataframe['Entry'] - self.dataframe['TP']) * (self.dataframe['LOTS'] * 100), 2)
  5. else:
  6. self.dataframe['PnL_Profit'] = round((self.dataframe['Entry'] - self.dataframe['TP']) * (self.dataframe['LOTS'] * 100000), 2)

这是根据您提供的代码的中文翻译。

英文:

I've a Dataframe (i write only the interested column)

Symbol Entry TP LOTS
CAD 1.023 1.33 1
EUR 1.53 1.43 3
JPY 165.12 166 10
XAU 1956 1960 7

what im trying to do is create a new column an add a value.
This value is the Profit And Loss of the trade.
The trouble is that CAD and EUR needs the same calculation, JPY a different one and XAU another one different. So i need to add the value to new column but based on condition.

i tried this simple way but i get an ValueError:

  1. if self.dataframe['Symbol'] in ['CAD','EUR']:
  2. self.dataframe['PnL_Profit'] = round((self.dataframe['Entry'] - self.dataframe['TP']) * (self.dataframe['Lots_Size'] * 100000) / self.dataframe['TP'],2)
  3. elif self.dataframe['Symbol'] == 'XAU':
  4. self.dataframe['PnL_Profit'] = round((self.dataframe['Entry'] - self.dataframe['TP']) * (self.dataframe['Lots_Size'] * 100),2)
  5. else:
  6. self.dataframe['PnL_Profit'] = round((self.dataframe['Entry'] - self.dataframe['TP']) * (self.dataframe['Lots_Size'] * 100000),2)

But i get this kind of error:

  1. raise ValueError(
  2. ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

im stuck, apparently everything is write good, but i dont know where's the error. i tried also Match...Case but i get the same error

答案1

得分: 1

在Pandas中,似乎无法像你当前使用的方式那样使用标准的Python if-else条件块。我认为你遇到的错误是因为Python不知道如何解释self.dataframe['Symbol']在['CAD','EUR']中的情况,因为当'Symbol'是一个Pandas Series而不是单个值时,这是不明确的。

也许你可以使用以下类似的方法:

  1. # 为条件创建掩码
  2. mask_cad_eur = self.dataframe['Symbol'].isin(['CAD','EUR'])
  3. mask_xau = self.dataframe['Symbol'] == 'XAU'
  4. mask_others = ~(mask_cad_eur | mask_xau) # 此掩码用于不是'CAD','EUR'或'XAU'的符号
  5. # 根据每个条件计算'PnL_Profit'
  6. self.dataframe.loc[mask_cad_eur, 'PnL_Profit'] = ((self.dataframe.loc[mask_cad_eur, 'Entry'] - self.dataframe.loc[mask_cad_eur, 'TP']) * self.dataframe.loc[mask_cad_eur, 'LOTS'] * 100000) / self.dataframe.loc[mask_cad_eur, 'TP']
  7. self.dataframe.loc[mask_xau, 'PnL_Profit'] = (self.dataframe.loc[mask_xau, 'Entry'] - self.dataframe.loc[mask_xau, 'TP']) * self.dataframe.loc[mask_xau, 'LOTS'] * 100
  8. self.dataframe.loc[mask_others, 'PnL_Profit'] = (self.dataframe.loc[mask_others, 'Entry'] - self.dataframe.loc[mask_others, 'TP']) * self.dataframe.loc[mask_others, 'LOTS'] * 100000
  9. # 将结果四舍五入到2位小数
  10. self.dataframe['PnL_Profit'] = self.dataframe['PnL_Profit'].round(2)

这将在你的数据框中创建一个名为'PnL_Profit'的新列,其中每行的值根据你的条件计算而来。

我注意到在你的代码中,你使用了Lots_Size,但在提供的数据框中它被命名为LOTS。所以,我在提供的代码中使用了LOTS。请根据你的数据框进行更正。

英文:

It seems to me in Pandas, you can't use the standard Python if-else conditional block in the way you're using it. I believe the error you're getting is because Python does not know how to interpret self.dataframe['Symbol'] in ['CAD','EUR'], as this is ambiguous when 'Symbol' is a Pandas Series, not a single value.

Maybe you can use something like the below:

  1. # create masks for the conditions
  2. mask_cad_eur = self.dataframe['Symbol'].isin(['CAD','EUR'])
  3. mask_xau = self.dataframe['Symbol'] == 'XAU'
  4. mask_others = ~(mask_cad_eur | mask_xau) # this mask is for symbols that are neither 'CAD', 'EUR', nor 'XAU'
  5. # calculate 'PnL_Profit' for each condition
  6. self.dataframe.loc[mask_cad_eur, 'PnL_Profit'] = ((self.dataframe.loc[mask_cad_eur, 'Entry'] - self.dataframe.loc[mask_cad_eur, 'TP']) * self.dataframe.loc[mask_cad_eur, 'LOTS'] * 100000) / self.dataframe.loc[mask_cad_eur, 'TP']
  7. self.dataframe.loc[mask_xau, 'PnL_Profit'] = (self.dataframe.loc[mask_xau, 'Entry'] - self.dataframe.loc[mask_xau, 'TP']) * self.dataframe.loc[mask_xau, 'LOTS'] * 100
  8. self.dataframe.loc[mask_others, 'PnL_Profit'] = (self.dataframe.loc[mask_others, 'Entry'] - self.dataframe.loc[mask_others, 'TP']) * self.dataframe.loc[mask_others, 'LOTS'] * 100000
  9. # round the results to 2 decimal places
  10. self.dataframe['PnL_Profit'] = self.dataframe['PnL_Profit'].round(2)

This will create a new column 'PnL_Profit' in your dataframe where each row's value is calculated based on your conditions.

I note that in your code you've used Lots_Size but in the dataframe provided it's named LOTS. So, I used LOTS in the code provided. Make sure to correct it based on your dataframe.

答案2

得分: 1

你可以使用一个公式字典,结合 eval 函数来实现:

  1. formulas = {'CAD': '(Entry-TP)*LOTS*100_000/TP',
  2. 'EUR': '(Entry-TP)*LOTS*100_000/TP',
  3. 'JPY': '(Entry-TP)*LOTS*100',
  4. 'XAU': '(Entry-TP)*LOTS*100_000',
  5. }
  6. df['PnL_Profit'] = (df.groupby('Symbol', group_keys=False)
  7. .apply(lambda g: g.eval(formulas[g.name]))
  8. .round(2)
  9. )

输出结果:

  1. Symbol Entry TP LOTS PnL_Profit
  2. 0 CAD 1.023 1.33 1 -23082.71
  3. 1 EUR 1.530 1.43 3 20979.02
  4. 2 JPY 165.120 166.00 10 -880.00
  5. 3 XAU 1956.000 1960.00 7 -2800000.00

为了避免重复定义公式,你也可以为它们取一个有意义的名字:

  1. formula_X = '(Entry-TP)*LOTS*100_000/TP'
  2. formula_Y = '(Entry-TP)*LOTS*100'
  3. formula_Z = '(Entry-TP)*LOTS*100_000'
  4. formulas = {'CAD': formula_X,
  5. 'EUR': formula_X,
  6. 'JPY': formula_Y,
  7. 'XAU': formula_Z,
  8. }
英文:

You could use a dictionary of formulas and combine it with eval:

  1. formulas = {'CAD': '(Entry-TP)*LOTS*100_000/TP',
  2. 'EUR': '(Entry-TP)*LOTS*100_000/TP',
  3. 'JPY': '(Entry-TP)*LOTS*100',
  4. 'XAU': '(Entry-TP)*LOTS*100_000',
  5. }
  6. df['PnL_Profit'] = (df.groupby('Symbol', group_keys=False)
  7. .apply(lambda g: g.eval(formulas[g.name]))
  8. .round(2)
  9. )

Output:

  1. Symbol Entry TP LOTS PnL_Profit
  2. 0 CAD 1.023 1.33 1 -23082.71
  3. 1 EUR 1.530 1.43 3 20979.02
  4. 2 JPY 165.120 166.00 10 -880.00
  5. 3 XAU 1956.000 1960.00 7 -2800000.00

To avoid duplicating the formula definitions it's also possible to name them, in particular if you find a meaningful name:

  1. formula_X = '(Entry-TP)*LOTS*100_000/TP'
  2. formula_Y = '(Entry-TP)*LOTS*100'
  3. formula_Z = '(Entry-TP)*LOTS*100_000'
  4. formulas = {'CAD': formula_X,
  5. 'EUR': formula_X,
  6. 'JPY': formula_Y,
  7. 'XAU': formula_Z,
  8. }

huangapple
  • 本文由 发表于 2023年7月14日 06:04:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76683522.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定