dr.filter()
------------------------------------------------------------------------------------##¶
- Single Condition Examples:
- Logic Operators: >, <, >=, <=, .between(), ==, !=
- .isin()
- String Boolean: .str.contains(), .str.startswith(), .str.endswith(), ....
- DateTime Boolean: .dt.is_month_start, .dt.is_month_end, ...
============================
- Negation of Condition: ~ (tilde) operator
============================
- Combine Multiple Conditions:
- & (and),
- | (or)
- Combine & and |
============================
- Columns with "bad" names: using f["col name"]
In [1]:
Copied!
import datar.all as dr
from datar import f
import pandas as pd
from pathlib import Path
from pipda import register_verb
dr.filter = register_verb(func=dr.filter_)
pd.set_option("display.width", 200)
# Get the path object pointing to the ``notebooks`` directory that contains *.csv files
data_dir = next(Path("/home").rglob("*/notebooks/*.csv")).parent
import datar.all as dr
from datar import f
import pandas as pd
from pathlib import Path
from pipda import register_verb
dr.filter = register_verb(func=dr.filter_)
pd.set_option("display.width", 200)
# Get the path object pointing to the ``notebooks`` directory that contains *.csv files
data_dir = next(Path("/home").rglob("*/notebooks/*.csv")).parent
In [2]:
Copied!
tb_pokemon = dr.tibble(
pd.read_csv(data_dir/"pokemon.csv")
>> dr.rename_with(lambda col: col.strip().replace(" ", "_").replace(".", "")) # Clean column names
>> dr.select(~f["#"]) # Drop the "#" column
>> dr.mutate(
Type_1 = f.Type_1.astype("category"), # convert to category (pandas style)
Type_2 = dr.as_factor(f.Type_2), # convert to category (datar style)
Generation = dr.as_ordered(f.Generation), # convert to ordered category (datar style)
Legendary = dr.as_logical(f.Legendary) # convert to boolean (datar style)
)
)
print(
tb_pokemon
>> dr.slice_head(n=5)
)
tb_pokemon = dr.tibble(
pd.read_csv(data_dir/"pokemon.csv")
>> dr.rename_with(lambda col: col.strip().replace(" ", "_").replace(".", "")) # Clean column names
>> dr.select(~f["#"]) # Drop the "#" column
>> dr.mutate(
Type_1 = f.Type_1.astype("category"), # convert to category (pandas style)
Type_2 = dr.as_factor(f.Type_2), # convert to category (datar style)
Generation = dr.as_ordered(f.Generation), # convert to ordered category (datar style)
Legendary = dr.as_logical(f.Legendary) # convert to boolean (datar style)
)
)
print(
tb_pokemon
>> dr.slice_head(n=5)
)
Name Type_1 Type_2 Total HP Attack Defense Sp_Atk Sp_Def Speed Generation Legendary
<str> <category> <category> <int64> <int64> <int64> <int64> <int64> <int64> <int64> <category> <bool>
0 Bulbasaur Grass Poison 318 45 49 49 65 65 45 1 False
1 Ivysaur Grass Poison 405 60 62 63 80 80 60 1 False
2 Venusaur Grass Poison 525 80 82 83 100 100 80 1 False
3 VenusaurMega Venusaur Grass Poison 625 80 100 123 122 120 80 1 False
4 Charmander Fire NaN 309 39 52 43 60 50 65 1 False
1. Single Condition Examples¶
In [4]:
Copied!
##---------------------------------------------------##
## Logic Operators: >, <, >=, <=, .between(), ==, != ##
##---------------------------------------------------##
#-------------
## > (greater than)
#-------------
print(
tb_pokemon
>> dr.filter(f.Attack > 150)
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Attack, f.Legendary)
>> dr.slice_head(n=5)
)
##---------------------------------------------------##
## Logic Operators: >, <, >=, <=, .between(), ==, != ##
##---------------------------------------------------##
#-------------
## > (greater than)
#-------------
print(
tb_pokemon
>> dr.filter(f.Attack > 150)
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Attack, f.Legendary)
>> dr.slice_head(n=5)
)
Name Type_1 Type_2 Attack Legendary
<str> <category> <category> <int64> <bool>
137 PinsirMega Pinsir Bug Flying 155 False
141 GyaradosMega Gyarados Water Dark 155 False
163 MewtwoMega Mewtwo X Psychic Fighting 190 True
232 HeracrossMega Heracross Bug Fighting 185 False
268 TyranitarMega Tyranitar Rock Dark 164 False
In [5]:
Copied!
print(
tb_pokemon
>> dr.filter(f.Sp_Atk > f.Attack*2)
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Attack, f.Sp_Atk, f.Legendary)
>> dr.slice_head(n=5)
)
print(
tb_pokemon
>> dr.filter(f.Sp_Atk > f.Attack*2)
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Attack, f.Sp_Atk, f.Legendary)
>> dr.slice_head(n=5)
)
Name Type_1 Type_2 Attack Sp_Atk Legendary
<str> <category> <category> <int64> <int64> <bool>
68 Abra Psychic NaN 20 105 False
69 Kadabra Psychic NaN 35 120 False
70 Alakazam Psychic NaN 50 135 False
71 AlakazamMega Alakazam Psychic NaN 50 175 False
88 Magnemite Electric Steel 35 95 False
In [6]:
Copied!
#-------------
## < (less than)
#-------------
print(
tb_pokemon
>> dr.filter(f.Speed < 15)
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Speed, f.Legendary)
>> dr.slice_head(n=5)
)
#-------------
## < (less than)
#-------------
print(
tb_pokemon
>> dr.filter(f.Speed < 15)
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Speed, f.Legendary)
>> dr.slice_head(n=5)
)
Name Type_1 Type_2 Speed Legendary
<str> <category> <category> <int64> <bool>
230 Shuckle Bug Rock 5 False
359 Trapinch Ground NaN 10 False
486 Bonsly Rock NaN 10 False
495 Munchlax Normal NaN 5 False
658 Ferroseed Grass Steel 10 False
In [7]:
Copied!
print(
tb_pokemon
>> dr.filter(f.Defense < f.Attack*0.5)
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Attack, f.Defense, f.Legendary)
>> dr.slice_head(n=5)
)
print(
tb_pokemon
>> dr.filter(f.Defense < f.Attack*0.5)
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Attack, f.Defense, f.Legendary)
>> dr.slice_head(n=5)
)
Name Type_1 Type_2 Attack Defense Legendary
<str> <category> <category> <int64> <int64> <bool>
18 Beedrill Bug Poison 90 40 False
19 BeedrillMega Beedrill Bug Poison 150 40 False
44 Jigglypuff Normal Fairy 45 20 False
55 Diglett Ground NaN 55 25 False
61 Mankey Fighting NaN 80 35 False
In [8]:
Copied!
'''
THE SAME FOR ">=" (greater or equal) and "<=" (less or equal)
'''
'''
THE SAME FOR ">=" (greater or equal) and "<=" (less or equal)
'''
Out[8]:
'\nTHE SAME FOR ">=" (greater or equal) and "<=" (less or equal)\n'
In [9]:
Copied!
#-------------
## .between(left, right, inclusive='both')
#-------------
'''
inclusive="both" (default): [left, right] or left <= x <= right
inclusive="neither": (left, right) or left < x < right
inclusive="left": [left, right) or left <= x < right
inclusive="right": (left, right] or left < x <= right
'''
print(
tb_pokemon
>> dr.filter(f.Defense.between(100, 150, inclusive="both"))
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Defense, f.Legendary)
>> dr.slice_head(n=5)
)
#-------------
## .between(left, right, inclusive='both')
#-------------
'''
inclusive="both" (default): [left, right] or left <= x <= right
inclusive="neither": (left, right) or left < x < right
inclusive="left": [left, right) or left <= x < right
inclusive="right": (left, right] or left < x <= right
'''
print(
tb_pokemon
>> dr.filter(f.Defense.between(100, 150, inclusive="both"))
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Defense, f.Legendary)
>> dr.slice_head(n=5)
)
Name Type_1 Type_2 Defense Legendary
<str> <category> <category> <int64> <bool>
3 VenusaurMega Venusaur Grass Poison 123 False
7 CharizardMega Charizard X Fire Dragon 111 False
11 Blastoise Water NaN 100 False
12 BlastoiseMega Blastoise Water NaN 120 False
33 Sandslash Ground NaN 110 False
In [10]:
Copied!
#-------------
## == (equal)
#-------------
print(
tb_pokemon
>> dr.filter(f.Type_1 == 'Fire')
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_head(n=5)
)
#-------------
## == (equal)
#-------------
print(
tb_pokemon
>> dr.filter(f.Type_1 == 'Fire')
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_head(n=5)
)
Name Type_1 Type_2 Total Legendary
<str> <category> <category> <int64> <bool>
4 Charmander Fire NaN 309 False
5 Charmeleon Fire NaN 405 False
6 Charizard Fire Flying 534 False
7 CharizardMega Charizard X Fire Dragon 634 False
8 CharizardMega Charizard Y Fire Flying 634 False
In [11]:
Copied!
#-------------
## != (not equal)
#-------------
print(
tb_pokemon
>> dr.filter(f.Type_1 != 'Fire')
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_head(n=5)
)
#-------------
## != (not equal)
#-------------
print(
tb_pokemon
>> dr.filter(f.Type_1 != 'Fire')
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_head(n=5)
)
Name Type_1 Type_2 Total Legendary
<str> <category> <category> <int64> <bool>
0 Bulbasaur Grass Poison 318 False
1 Ivysaur Grass Poison 405 False
2 Venusaur Grass Poison 525 False
3 VenusaurMega Venusaur Grass Poison 625 False
9 Squirtle Water NaN 314 False
In [12]:
Copied!
##--------------------------##
## .isin() ##
##--------------------------##
print(
tb_pokemon
>> dr.filter(f.Type_1.isin(['Fire', 'Water'])) # Type_1 in the list ['Fire', 'Water']
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_tail(n=5)
)
##--------------------------##
## .isin() ##
##--------------------------##
print(
tb_pokemon
>> dr.filter(f.Type_1.isin(['Fire', 'Water'])) # Type_1 in the list ['Fire', 'Water']
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_tail(n=5)
)
Name Type_1 Type_2 Total Legendary
<str> <category> <category> <int64> <bool>
735 Litleo Fire Normal 369 False
736 Pyroar Fire Normal 507 False
762 Clauncher Water NaN 330 False
763 Clawitzer Water NaN 500 False
799 Volcanion Fire Water 600 True
In [13]:
Copied!
print(
tb_pokemon
>> dr.filter(f.Generation.isin(['4', '6'])) # Generation in the list ['4', '6']
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Generation, f.Legendary)
)
print(
tb_pokemon
>> dr.filter(f.Generation.isin(['4', '6'])) # Generation in the list ['4', '6']
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Generation, f.Legendary)
)
Empty Tibble Columns: [Name, Type_1, Type_2, Total, Generation, Legendary] Index: []
In [14]:
Copied!
##--------------------------##
## String Boolean ##
##--------------------------##
print(
tb_pokemon
>> dr.filter(f.Name.str.contains('Mega')) # Name contains the substring 'Mega'
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_head(n=5)
)
##--------------------------##
## String Boolean ##
##--------------------------##
print(
tb_pokemon
>> dr.filter(f.Name.str.contains('Mega')) # Name contains the substring 'Mega'
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_head(n=5)
)
Name Type_1 Type_2 Total Legendary
<str> <category> <category> <int64> <bool>
3 VenusaurMega Venusaur Grass Poison 625 False
7 CharizardMega Charizard X Fire Dragon 634 False
8 CharizardMega Charizard Y Fire Flying 634 False
12 BlastoiseMega Blastoise Water NaN 630 False
19 BeedrillMega Beedrill Bug Poison 495 False
In [15]:
Copied!
print(
tb_pokemon
>> dr.filter(f.Name.str.startswith('Tor')) # Name starts with the substring 'Tor'
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_head(n=5)
)
print(
tb_pokemon
>> dr.filter(f.Name.str.startswith('Tor')) # Name starts with the substring 'Tor'
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_head(n=5)
)
Name Type_1 Type_2 Total Legendary
<str> <category> <category> <int64> <bool>
276 Torchic Fire NaN 310 False
355 Torkoal Fire NaN 470 False
434 Torterra Grass Ground 525 False
702 TornadusIncarnate Forme Flying NaN 580 True
703 TornadusTherian Forme Flying NaN 580 True
In [16]:
Copied!
print(
tb_pokemon
>> dr.filter(f.Name.str.endswith('ite')) # Name ends with the substring 'ite'
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_head(n=5)
)
print(
tb_pokemon
>> dr.filter(f.Name.str.endswith('ite')) # Name ends with the substring 'ite'
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_head(n=5)
)
Name Type_1 Type_2 Total Legendary
<str> <category> <category> <int64> <bool>
88 Magnemite Electric Steel 325 False
161 Dragonite Dragon Flying 600 False
334 Meditite Fighting Psychic 280 False
492 Gabite Dragon Ground 410 False
558 Pignite Fire Fighting 418 False
In [17]:
Copied!
##--------------------------##
## DateTime Boolean ##
##--------------------------##
tb_emp = dr.tibble(
pd.read_csv(
filepath_or_buffer=data_dir/"emp.csv",
parse_dates=["start_date"]
)
)
print(
tb_emp
>> dr.filter(f.start_date.dt.is_month_start)
)
##--------------------------##
## DateTime Boolean ##
##--------------------------##
tb_emp = dr.tibble(
pd.read_csv(
filepath_or_buffer=data_dir/"emp.csv",
parse_dates=["start_date"]
)
)
print(
tb_emp
>> dr.filter(f.start_date.dt.is_month_start)
)
id name salary start_date dept <int64> <str> <float64> <datetime64[us]> <str> 0 1 Rick 623.3 2012-01-01 IT
In [18]:
Copied!
print(
tb_emp
>> dr.filter(f.start_date.dt.is_leap_year)
)
print(
tb_emp
>> dr.filter(f.start_date.dt.is_leap_year)
)
id name salary start_date dept <int64> <str> <float64> <datetime64[us]> <str> 0 1 Rick 623.3 2012-01-01 IT
2. Negation of Condition: ~ (tilde) operator¶
In [19]:
Copied!
print(
tb_pokemon
>> dr.filter(~(f.Type_1 == 'Fire')) # Type_1 not equal to 'Fire'
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_sample(n=5, random_state=1)
)
print(
tb_pokemon
>> dr.filter(~(f.Type_1 == 'Fire')) # Type_1 not equal to 'Fire'
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_sample(n=5, random_state=1)
)
Name Type_1 Type_2 Total Legendary
<str> <category> <category> <int64> <bool>
291 Cascoon Bug NaN 205 False
554 Snivy Grass NaN 308 False
627 Archen Rock Flying 401 False
768 Amaura Rock Ice 362 False
101 Gengar Ghost Poison 500 False
In [20]:
Copied!
print(
tb_pokemon
>> dr.filter(~f.Type_2.isin(['Flying', 'Dragon'])) # Type_2 not in the list ['Flying', 'Dragon']
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_sample(n=5, random_state=2)
)
print(
tb_pokemon
>> dr.filter(~f.Type_2.isin(['Flying', 'Dragon'])) # Type_2 not in the list ['Flying', 'Dragon']
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
>> dr.slice_sample(n=5, random_state=2)
)
Name Type_1 Type_2 Total Legendary
<str> <category> <category> <int64> <bool>
122 Tangela Grass NaN 435 False
246 Houndour Dark Fire 330 False
740 Skiddo Grass NaN 350 False
732 Scatterbug Bug NaN 200 False
350 Wailmer Water NaN 400 False
3. Combine Multiple Conditions: & (and), | (or)¶
In [23]:
Copied!
##----------------------##
## & (and) ##
##----------------------##
'''True if only all the conditions (clauses) are True.'''
print(
tb_pokemon
>> dr.filter((f.Type_1 == 'Fire') & (f.Attack > 100)) # Type_1 equal to 'Fire' AND Attack greater than 100
>> dr.select(f.Name, f.Type_1, f.Attack)
>> dr.slice_head(n=5)
)
##----------------------##
## & (and) ##
##----------------------##
'''True if only all the conditions (clauses) are True.'''
print(
tb_pokemon
>> dr.filter((f.Type_1 == 'Fire') & (f.Attack > 100)) # Type_1 equal to 'Fire' AND Attack greater than 100
>> dr.select(f.Name, f.Type_1, f.Attack)
>> dr.slice_head(n=5)
)
Name Type_1 Attack
<str> <category> <int64>
7 CharizardMega Charizard X Fire 130
8 CharizardMega Charizard Y Fire 104
64 Arcanine Fire 110
147 Flareon Fire 130
263 Entei Fire 115
In [24]:
Copied!
print(
tb_pokemon
>> dr.filter((f.Type_1 == 'Fire') & (f.Attack > 100) & (f.Generation == 5))
>> dr.select(f.Name, f.Type_1, f.Attack, f.Generation, f.Legendary)
)
print(
tb_pokemon
>> dr.filter((f.Type_1 == 'Fire') & (f.Attack > 100) & (f.Generation == 5))
>> dr.select(f.Name, f.Type_1, f.Attack, f.Generation, f.Legendary)
)
Name Type_1 Attack Generation Legendary
<str> <category> <int64> <category> <bool>
559 Emboar Fire 123 5 False
615 DarmanitanStandard Mode Fire 140 5 False
In [25]:
Copied!
##-----------------------##
## | (or) ##
##-----------------------##
'''False if only all the conditions (clauses) are False.'''
print(
tb_pokemon
>> dr.filter((f.Type_1 == 'Fire') | (f.Type_1 == 'Water')) # Type_1 equal to 'Fire' OR Type_1 equal to 'Water'
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
)
##-----------------------##
## | (or) ##
##-----------------------##
'''False if only all the conditions (clauses) are False.'''
print(
tb_pokemon
>> dr.filter((f.Type_1 == 'Fire') | (f.Type_1 == 'Water')) # Type_1 equal to 'Fire' OR Type_1 equal to 'Water'
>> dr.select(f.Name, f.Type_1, f.Type_2, f.Total, f.Legendary)
)
Name Type_1 Type_2 Total Legendary
<str> <category> <category> <int64> <bool>
4 Charmander Fire NaN 309 False
5 Charmeleon Fire NaN 405 False
6 Charizard Fire Flying 534 False
7 CharizardMega Charizard X Fire Dragon 634 False
.. ... ... ... ... ...
8 CharizardMega Charizard Y Fire Flying 634 False
735 Litleo Fire Normal 369 False
736 Pyroar Fire Normal 507 False
762 Clauncher Water NaN 330 False
763 Clawitzer Water NaN 500 False
799 Volcanion Fire Water 600 True
[164 rows x 5 columns]
In [26]:
Copied!
print(
tb_pokemon
>> dr.filter((f.Attack > f.Defense) | (f.Sp_Atk <= f.Sp_Def))
>> dr.select(f.Name, f.Attack, f.Defense, f.Sp_Atk, f.Sp_Def)
>> dr.slice_head(n=5)
)
print(
tb_pokemon
>> dr.filter((f.Attack > f.Defense) | (f.Sp_Atk <= f.Sp_Def))
>> dr.select(f.Name, f.Attack, f.Defense, f.Sp_Atk, f.Sp_Def)
>> dr.slice_head(n=5)
)
Name Attack Defense Sp_Atk Sp_Def
<str> <int64> <int64> <int64> <int64>
0 Bulbasaur 49 49 65 65
1 Ivysaur 62 63 80 80
2 Venusaur 82 83 100 100
4 Charmander 52 43 60 50
5 Charmeleon 64 58 80 65
In [27]:
Copied!
##---------------------------##
## Combine & and | ##
##---------------------------##
print(
tb_pokemon
>> dr.filter(
((f.Type_1 == 'Fire') | (f.Type_1 == 'Water')) & (f.Attack > 100)
) # (Type_1 equal to 'Fire' OR Type_1 equal to 'Water') AND Attack greater than 100
>> dr.select(f.Name, f.Type_1, f.Attack, f.Legendary)
>> dr.slice_head(n=5)
)
##---------------------------##
## Combine & and | ##
##---------------------------##
print(
tb_pokemon
>> dr.filter(
((f.Type_1 == 'Fire') | (f.Type_1 == 'Water')) & (f.Attack > 100)
) # (Type_1 equal to 'Fire' OR Type_1 equal to 'Water') AND Attack greater than 100
>> dr.select(f.Name, f.Type_1, f.Attack, f.Legendary)
>> dr.slice_head(n=5)
)
Name Type_1 Attack Legendary
<str> <category> <int64> <bool>
7 CharizardMega Charizard X Fire 130 False
8 CharizardMega Charizard Y Fire 104 False
12 BlastoiseMega Blastoise Water 103 False
64 Arcanine Fire 110 False
106 Krabby Water 105 False
4. Columns with "bad" names: using f["col name"]¶
In [32]:
Copied!
tb_lifexp = dr.tibble(
pd.read_csv(
filepath_or_buffer=data_dir/"life_expectancy.csv"
)
)
for col_name in tb_lifexp.columns:
print(repr(col_name))
tb_lifexp = dr.tibble(
pd.read_csv(
filepath_or_buffer=data_dir/"life_expectancy.csv"
)
)
for col_name in tb_lifexp.columns:
print(repr(col_name))
'Country' 'Year' 'Status' 'Life expectancy ' 'Adult Mortality' 'infant deaths' 'Alcohol' 'percentage expenditure' 'Hepatitis B' 'Measles ' ' BMI ' 'under-five deaths ' 'Polio' 'Total expenditure' 'Diphtheria ' ' HIV/AIDS' 'GDP' 'Population' ' thinness 1-19 years' ' thinness 5-9 years' 'Income composition of resources' 'Schooling'
In [33]:
Copied!
##-----------------------------------------##
## Using f['col name'] for bad column name ##
##-----------------------------------------##
print(
tb_lifexp
>> dr.filter((f['Life expectancy '] > 80) & (f[' thinness 5-9 years'] <= 2) & (f.Year == 2015))
>> dr.select(f.Country, f.Year, f['Life expectancy '], f[' thinness 5-9 years'])
>> dr.slice_head(n=5)
)
##-----------------------------------------##
## Using f['col name'] for bad column name ##
##-----------------------------------------##
print(
tb_lifexp
>> dr.filter((f['Life expectancy '] > 80) & (f[' thinness 5-9 years'] <= 2) & (f.Year == 2015))
>> dr.select(f.Country, f.Year, f['Life expectancy '], f[' thinness 5-9 years'])
>> dr.slice_head(n=5)
)
Country Year Life expectancy thinness 5-9 years
<str> <int64> <float64> <float64>
112 Australia 2015 82.8 0.6
240 Belgium 2015 81.1 1.0
496 Canada 2015 82.2 0.5
544 Chile 2015 85.0 0.8
673 Cyprus 2015 85.0 1.0