Pandy warunkowe utworzenie kolumny serii / ramki danych
Mam ramkę danych zgodnie z poniższymi wersjami:
Type Set
1 A Z
2 B Z
3 B X
4 C Y
Chcę dodać kolejną kolumnę do ramki danych (lub wygenerować serię) o tej samej długości co ramka danych (równa liczba rekordów/wierszy), która ustawi kolor 'green'
if Set == 'Z'
i 'red'
if Set
równa się cokolwiek innego.
Jaki jest najlepszy sposób, aby to zrobić?
9 answers
Jeśli masz tylko dwie opcje do wyboru:
df['color'] = np.where(df['Set']=='Z', 'green', 'red')
Na przykład,
import pandas as pd
import numpy as np
df = pd.DataFrame({'Type':list('ABBC'), 'Set':list('ZZXY')})
df['color'] = np.where(df['Set']=='Z', 'green', 'red')
print(df)
Set Type color
0 Z A green
1 Z B green
2 X B red
3 Y C red
Jeśli masz więcej niż dwa warunki, użyj np.select
. Na przykład, jeśli chcesz color
BYĆ
-
yellow
kiedy(df['Set'] == 'Z') & (df['Type'] == 'A')
- inaczej
blue
Kiedy(df['Set'] == 'Z') & (df['Type'] == 'B')
- inaczej
purple
Kiedy(df['Type'] == 'B')
- inaczej
black
,
Następnie użyj
df = pd.DataFrame({'Type':list('ABBC'), 'Set':list('ZZXY')})
conditions = [
(df['Set'] == 'Z') & (df['Type'] == 'A'),
(df['Set'] == 'Z') & (df['Type'] == 'B'),
(df['Type'] == 'B')]
choices = ['yellow', 'blue', 'purple']
df['color'] = np.select(conditions, choices, default='black')
print(df)
Co daje
Set Type color
0 Z A yellow
1 Z B blue
2 X B purple
3 Y C black
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
2020-01-09 21:47:51
Rozumienie listy jest innym sposobem warunkowego tworzenia kolejnej kolumny. Jeśli pracujesz z obiektowymi typami dtypów w kolumnach, tak jak w przykładzie, składanie list zazwyczaj przewyższa większość innych metod.
Przykładowa lista:
df['color'] = ['red' if x == 'Z' else 'green' for x in df['Set']]
%testy czasu:
import pandas as pd
import numpy as np
df = pd.DataFrame({'Type':list('ABBC'), 'Set':list('ZZXY')})
%timeit df['color'] = ['red' if x == 'Z' else 'green' for x in df['Set']]
%timeit df['color'] = np.where(df['Set']=='Z', 'green', 'red')
%timeit df['color'] = df.Set.map( lambda x: 'red' if x == 'Z' else 'green')
1000 loops, best of 3: 239 µs per loop
1000 loops, best of 3: 523 µs per loop
1000 loops, best of 3: 263 µs per loop
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-08-16 16:49:28
Innym sposobem, w jaki można to osiągnąć jest
df['color'] = df.Set.map( lambda x: 'red' if x == 'Z' else 'green')
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
2014-06-06 04:43:52
Oto kolejny sposób na skórkę tego kota, używając słownika do mapowania nowych wartości na kluczach na liście:
def map_values(row, values_dict):
return values_dict[row]
values_dict = {'A': 1, 'B': 2, 'C': 3, 'D': 4}
df = pd.DataFrame({'INDICATOR': ['A', 'B', 'C', 'D'], 'VALUE': [10, 9, 8, 7]})
df['NEW_VALUE'] = df['INDICATOR'].apply(map_values, args = (values_dict,))
Jak to wygląda:
df
Out[2]:
INDICATOR VALUE NEW_VALUE
0 A 10 1
1 B 9 2
2 C 8 3
3 D 7 4
To podejście może być bardzo skuteczne, gdy masz wiele instrukcji typu ifelse
do złożenia (tj. wiele unikalnych wartości do zastąpienia).
I oczywiście zawsze możesz to zrobić:
df['NEW_VALUE'] = df['INDICATOR'].map(values_dict)
Ale to podejście jest ponad trzy razy wolniejsze niż podejście z góry, na mojej maszynie.
I ty też możesz to zrobić, użycie dict.get
:
df['NEW_VALUE'] = [values_dict.get(v, None) for v in df['INDICATOR']]
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-16 20:59:07
Poniższy tekst jest wolniejszy niż podejście timed tutaj, ale możemy obliczyć dodatkową kolumnę na podstawie zawartości więcej niż jednej kolumny, a więcej niż dwie wartości mogą być obliczone dla dodatkowej kolumny.
Prosty przykład z użyciem kolumny "Set":
def set_color(row):
if row["Set"] == "Z":
return "red"
else:
return "green"
df = df.assign(color=df.apply(set_color, axis=1))
print(df)
Set Type color
0 Z A red
1 Z B red
2 X B green
3 Y C green
Przykład z większą liczbą kolorów i większą liczbą kolumn:
def set_color(row):
if row["Set"] == "Z":
return "red"
elif row["Type"] == "C":
return "blue"
else:
return "green"
df = df.assign(color=df.apply(set_color, axis=1))
print(df)
Set Type color
0 Z A red
1 Z B red
2 X B green
3 Y C blue
W 2009 roku firma została założona przez prof.]}
Możliwe jest również użycie plydata do tego typu rzeczy (wydaje się to nawet wolniejsze niż użycie assign
i apply
).
from plydata import define, if_else
Proste if_else
:
df = define(df, color=if_else('Set=="Z"', '"red"', '"green"'))
print(df)
Set Type color
0 Z A red
1 Z B red
2 X B green
3 Y C green
Zagnieżdżone if_else
:
df = define(df, color=if_else(
'Set=="Z"',
'"red"',
if_else('Type=="C"', '"green"', '"blue"')))
print(df)
Set Type color
0 Z A red
1 Z B red
2 X B blue
3 Y C green
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
2019-06-21 15:23:50
Możesz po prostu użyć potężnej metody .loc
i użyć jednego warunku lub kilku w zależności od potrzeb (testowane z pandas=1.0.5).
Podsumowanie Kodu:
df=pd.DataFrame(dict(Type='A B B C'.split(), Set='Z Z X Y'.split()))
df['Color'] = "red"
df.loc[(df['Set']=="Z"), 'Color'] = "green"
#practice!
df.loc[(df['Set']=="Z")&(df['Type']=="B")|(df['Type']=="C"), 'Color'] = "purple"
Wyjaśnienie:
df=pd.DataFrame(dict(Type='A B B C'.split(), Set='Z Z X Y'.split()))
# df so far:
Type Set
0 A Z
1 B Z
2 B X
3 C Y
Dodaj kolumnę "kolor" i ustaw wszystkie wartości na "czerwony"
df['Color'] = "red"
Zastosuj jeden warunek:
df.loc[(df['Set']=="Z"), 'Color'] = "green"
# df:
Type Set Color
0 A Z green
1 B Z green
2 B X red
3 C Y red
Lub wiele warunków, jeśli chcesz:
df.loc[(df['Set']=="Z")&(df['Type']=="B")|(df['Type']=="C"), 'Color'] = "purple"
Możesz przeczytać o operatorach logicznych i warunkowym wyborze pand tutaj: operatory logiczne do indeksowania boolowskiego w Pandy
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
2021-01-31 07:17:13
Jedna wkładka z metodą .apply()
jest następująca:
df['color'] = df['Set'].apply(lambda set_: 'green' if set_=='Z' else 'red')
Po tym, df
ramka danych wygląda tak:
>>> print(df)
Type Set color
0 A Z green
1 B Z green
2 B X red
3 C Y red
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
2019-10-10 14:30:03
Jeśli pracujesz z massive data, najlepiej byłoby zastosować podejście memoized:
# First create a dictionary of manually stored values
color_dict = {'Z':'red'}
# Second, build a dictionary of "other" values
color_dict_other = {x:'green' for x in df['Set'].unique() if x not in color_dict.keys()}
# Next, merge the two
color_dict.update(color_dict_other)
# Finally, map it to your column
df['color'] = df['Set'].map(color_dict)
takie podejście będzie najszybsze, gdy masz wiele powtarzających się wartości. moją ogólną zasadą jest zapamiętanie, kiedy: data_size
> 10**4
& n_distinct
data_size/4
E. X. Memoize w przypadku 10,000 wierszy z 2,500 lub mniej odrębnych wartości.
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
2019-12-08 18:42:01
Możesz używać metod pandy where
Oraz mask
:
df['color'] = 'green'
df['color'] = df['color'].where(df['Set']=='Z', other='red')
# Replace values where the condition is False
Lub
df['color'] = 'red'
df['color'] = df['color'].mask(df['Set']=='Z', other='green')
# Replace values where the condition is True
Wyjście:
Type Set color
1 A Z green
2 B Z green
3 B X red
4 C Y red
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
2021-02-02 07:55:39