Chcę pomnożyć dwie kolumny w ramce danych i dodać wynik do nowej kolumny
Próbuję pomnożyć dwie istniejące kolumny w ramce danych pandy (orders_df) - ceny (cena zamknięcia zapasów) i ilość (ilości zapasów) i dodać obliczenia do nowej kolumny o nazwie "wartość". Z jakiegoś powodu, gdy uruchamiam ten kod, wszystkie wiersze w kolumnie "Wartość" są liczbami dodatnimi, podczas gdy niektóre wiersze powinny być ujemne. Pod Kolumną działania w ramce danych znajduje się siedem wierszy z ciągiem "Sprzedaj" i siedem z ciągiem "kupuj".
for i in orders_df.Action:
if i == 'Sell':
orders_df['Value'] = orders_df.Prices*orders_df.Amount
elif i == 'Buy':
orders_df['Value'] = -orders_df.Prices*orders_df.Amount)
Proszę dać mi znać co robię źle !
5 answers
Jeśli jesteśmy gotowi poświęcić zwięzłość rozwiązania Haydena, można również zrobić coś takiego:]}
In [22]: orders_df['C'] = orders_df.Action.apply(
lambda x: (1 if x == 'Sell' else -1))
In [23]: orders_df # New column C represents the sign of the transaction
Out[23]:
Prices Amount Action C
0 3 57 Sell 1
1 89 42 Sell 1
2 45 70 Buy -1
3 6 43 Sell 1
4 60 47 Sell 1
5 19 16 Buy -1
6 56 89 Sell 1
7 3 28 Buy -1
8 56 69 Sell 1
9 90 49 Buy -1
Teraz wyeliminowaliśmy potrzebę if
stwierdzenia. Używając DataFrame.apply()
, usuwamy również pętlę for
. Jak zauważył Hayden, operacje wektorowe są zawsze szybsze.
In [24]: orders_df['Value'] = orders_df.Prices * orders_df.Amount * orders_df.C
In [25]: orders_df # The resulting dataframe
Out[25]:
Prices Amount Action C Value
0 3 57 Sell 1 171
1 89 42 Sell 1 3738
2 45 70 Buy -1 -3150
3 6 43 Sell 1 258
4 60 47 Sell 1 2820
5 19 16 Buy -1 -304
6 56 89 Sell 1 4984
7 3 28 Buy -1 -84
8 56 69 Sell 1 3864
9 90 49 Buy -1 -4410
To rozwiązanie zajmuje dwie linie kodu zamiast jednej, ale jest nieco łatwiejsze do odczytania. Podejrzewam, że koszty obliczeniowe również są podobne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-27 20:05:45
Myślę, że eleganckim rozwiązaniem jest użycie where
metoda (Zobacz też API docs
):
In [37]: values = df.Prices * df.Amount
In [38]: df['Values'] = values.where(df.Action == 'Sell', other=-values)
In [39]: df
Out[39]:
Prices Amount Action Values
0 3 57 Sell 171
1 89 42 Sell 3738
2 45 70 Buy -3150
3 6 43 Sell 258
4 60 47 Sell 2820
5 19 16 Buy -304
6 56 89 Sell 4984
7 3 28 Buy -84
8 56 69 Sell 3864
9 90 49 Buy -4410
To powinno być najszybsze rozwiązanie.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-14 05:47:30
Możesz użyć ramki danych apply
"metoda": {]}
order_df['Value'] = order_df.apply(lambda row: (row['Prices']*row['Amount']
if row['Action']=='Sell'
else -row['Prices']*row['Amount']),
axis=1)
zwykle jest to szybsze stosowanie tych metod, a nie over for loops.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-27 18:59:12
Ponieważ to pytanie pojawiło się ponownie, myślę, że dobrym czystym podejściem jest użycie assign .
Kod jest dość wyrazisty i samoopisujący:
df = df.assign(Value = lambda x: x.Prices * x.Amount * x.Action.replace({'Buy' : 1, 'Sell' : -1}))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-25 14:18:35
Dla mnie jest to najczystsze i najbardziej intuicyjne:
values = []
for action in ['Sell','Buy']:
amounts = orders_df['Amounts'][orders_df['Action'==action]].values
if action == 'Sell':
prices = orders_df['Prices'][orders_df['Action'==action]].values
else:
prices = -1*orders_df['Prices'][orders_df['Action'==action]].values
values += list(amounts*prices)
orders_df['Values'] = values
Metoda .values
zwraca numpy array
pozwalając na łatwe mnożenie elementów, a następnie można skumulowane generowanie listy przez "dodanie" do niej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-25 14:06:12