添加条件下的值到新列 Pandas

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

Add values to new column Pandas with condition

问题

if self.dataframe['Symbol'].isin(['CAD', 'EUR']).any():
    self.dataframe['PnL_Profit'] = round((self.dataframe['Entry'] - self.dataframe['TP']) * (self.dataframe['LOTS'] * 100000) / self.dataframe['TP'], 2)
elif self.dataframe['Symbol'].eq('XAU').any():
    self.dataframe['PnL_Profit'] = round((self.dataframe['Entry'] - self.dataframe['TP']) * (self.dataframe['LOTS'] * 100), 2)
else:
    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:

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

But i get this kind of error:

        raise ValueError(
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而不是单个值时,这是不明确的。

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

# 为条件创建掩码
mask_cad_eur = self.dataframe['Symbol'].isin(['CAD','EUR'])
mask_xau = self.dataframe['Symbol'] == 'XAU'
mask_others = ~(mask_cad_eur | mask_xau)  # 此掩码用于不是'CAD','EUR'或'XAU'的符号

# 根据每个条件计算'PnL_Profit'
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']
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
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

# 将结果四舍五入到2位小数
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:

# create masks for the conditions
mask_cad_eur = self.dataframe['Symbol'].isin(['CAD','EUR'])
mask_xau = self.dataframe['Symbol'] == 'XAU'
mask_others = ~(mask_cad_eur | mask_xau)  # this mask is for symbols that are neither 'CAD', 'EUR', nor 'XAU'

# calculate 'PnL_Profit' for each condition
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']
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
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

# round the results to 2 decimal places
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 函数来实现:

formulas = {'CAD': '(Entry-TP)*LOTS*100_000/TP',
            'EUR': '(Entry-TP)*LOTS*100_000/TP',
            'JPY': '(Entry-TP)*LOTS*100',
            'XAU': '(Entry-TP)*LOTS*100_000',
            }

df['PnL_Profit'] = (df.groupby('Symbol', group_keys=False)
                  .apply(lambda g: g.eval(formulas[g.name]))
                  .round(2)
                )

输出结果:

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

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

formula_X = '(Entry-TP)*LOTS*100_000/TP'
formula_Y = '(Entry-TP)*LOTS*100'
formula_Z = '(Entry-TP)*LOTS*100_000'

formulas = {'CAD': formula_X,
            'EUR': formula_X,
            'JPY': formula_Y,
            'XAU': formula_Z,
            }
英文:

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

formulas = {'CAD': '(Entry-TP)*LOTS*100_000/TP',
            'EUR': '(Entry-TP)*LOTS*100_000/TP',
            'JPY': '(Entry-TP)*LOTS*100',
            'XAU': '(Entry-TP)*LOTS*100_000',
            }

df['PnL_Profit'] = (df.groupby('Symbol', group_keys=False)
                      .apply(lambda g: g.eval(formulas[g.name]))
                      .round(2)
                    )

Output:

  Symbol     Entry       TP  LOTS  PnL_Profit
0    CAD     1.023     1.33     1   -23082.71
1    EUR     1.530     1.43     3    20979.02
2    JPY   165.120   166.00    10     -880.00
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:

formula_X = '(Entry-TP)*LOTS*100_000/TP'
formula_Y = '(Entry-TP)*LOTS*100'
formula_Z = '(Entry-TP)*LOTS*100_000'

formulas = {'CAD': formula_X,
            'EUR': formula_X,
            'JPY': formula_Y,
            'XAU': formula_Z,
            }

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:

确定