Scraping Sports Data With Beautifulsoup - python

This is my first-time web scraping with beautiful soup and wanted to do a little project with hockey since I am a huge fan of the sport. I am a little stuck and wondering how to retrieve the header names of the stats for each player.
Here is my current code:
from bs4 import BeautifulSoup
import requests
import re
import pandas as pd
url = "http://www.espn.com/nhl/statistics/player/_/stat/points/year/2020/seasontype/2"
page = requests.get(url)
soup = BeautifulSoup(page.text, 'html.parser')
allStats = []
players = soup.find_all('tr', attrs={'class':re.compile('row player')})
for player in players:
stats = [stat.get_text() for stat in player.find_all('td')]
allStats += stats
body = soup.find_all('div', {"class":"wrapper"})
print(allStats)
allColumns = []
headers = soup.find_all('tr', attrs = {'class': 'colhead'})
for col in headers:
columns = [col.get_text() for col in headers.find_all('td')]
allColumns += columns
print(allColumns)
I am currently getting an error that says "ResultSet object has no attribute '%s' for the line
headers = soup.find_all('tr', attrs = {'class': 'colhead'})
Eventually, I want to get a list of all of the Stat Names being tracked and use that as the columns in a pandas dataframe that lists each player and their corresponding stats.
What's the best way to achieve this?
Thanks for your help!

There's a typo in your headers iteration that's why you're getting the error,
AttributeError: ResultSet object has no attribute 'find_all'. You're probably treating a list of elements like a single element. Did you call find_all() when you meant to call find()?
I suppose the expected result is as follows.
allColumns = []
headers = soup.find_all('tr', attrs = {'class': 'colhead'})
for header in headers:
columns = [head.get_text() for head in header.find_all('td')]
allColumns += columns
>>>
['', 'PP', 'SH', 'RK', 'PLAYER', 'TEAM', 'GP', 'G', 'A', 'PTS', '+/-', 'PIM', 'PTS/G', 'SOG', 'PCT', 'GWG', 'G', 'A', 'G', 'A', '', 'PP', 'SH', 'RK', 'PLAYER', 'TEAM', 'GP', 'G', 'A', 'PTS', '+/-', 'PIM', 'PTS/G', 'SOG', 'PCT', 'GWG', 'G', 'A', 'G', 'A', '', 'PP', 'SH', 'RK', 'PLAYER', 'TEAM', 'GP', 'G', 'A', 'PTS', '+/-', 'PIM', 'PTS/G', 'SOG', 'PCT', 'GWG', 'G', 'A', 'G', 'A', '', 'PP', 'SH', 'RK', 'PLAYER', 'TEAM', 'GP', 'G', 'A', 'PTS', '+/-', 'PIM', 'PTS/G', 'SOG', 'PCT', 'GWG', 'G', 'A', 'G', 'A']

Just as alternative, there is an espn api to get the statistics. But it's not documented as to how to pull a specicif season or season type:
http://site.api.espn.com/apis/site/v2/sports/football/nfl/statistics
However, you can pull out player stats from the nhl.com site with their api:
import requests
import pandas as pd
url = 'https://statsapi.web.nhl.com/api/v1/teams'
jsonDataTeams = requests.get(url).json()
teamsDict = {}
for team in jsonDataTeams['teams']:
rosterLink = 'https://statsapi.web.nhl.com' + team['link'] + '/roster'
teamsDict.update({team['name']:rosterLink})
playersDict = {}
for team, link in teamsDict.items():
jsonDataPlayers = requests.get(link).json()
for player in jsonDataPlayers['roster']:
playerLink = 'https://statsapi.web.nhl.com' + player['person']['link'] + '/stats'
playersDict.update({player['person']['fullName']:playerLink})
print ('Downloaded: %s' %team)
rows = []
count = 0
tot = len(playersDict)
for player, link in playersDict.items():
count+=1
payload = {'stats':'statsSingleSeason',
'season':'20192020'}
playerStats = requests.get(link, params=payload).json()
try:
row = playerStats['stats'][0]['splits'][0]['stat']
row.update({'player':player})
rows.append(row)
print ('%s of %s - Stats collected for: %s' %(count,tot,player))
except:
print ('%s of %s - No stats available for: %s' %(count,tot,player))
df = pd.DataFrame(rows)
Output:
print(df.head(20).to_string())
timeOnIce ot shutouts ties wins losses saves powerPlaySaves shortHandedSaves evenSaves shortHandedShots evenShots powerPlayShots savePercentage goalAgainstAverage games gamesStarted shotsAgainst goalsAgainst timeOnIcePerGame powerPlaySavePercentage shortHandedSavePercentage evenStrengthSavePercentage player assists goals pim shots hits powerPlayGoals powerPlayPoints powerPlayTimeOnIce evenTimeOnIce penaltyMinutes faceOffPct shotPct gameWinningGoals overTimeGoals shortHandedGoals shortHandedPoints shortHandedTimeOnIce blocked plusMinus points shifts evenTimeOnIcePerGame shortHandedTimeOnIcePerGame powerPlayTimeOnIcePerGame
0 2340:03 3.0 1.0 0.0 16.0 20.0 1186.0 132.0 26.0 1028.0 29.0 1110.0 155.0 0.917 2.7692 40 39.0 1294.0 108.0 58:30 85.161290 89.655172 92.612613 Corey Crawford NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 1179:36 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 69 NaN NaN NaN 17:05 NaN NaN NaN Travis Zajac 16.0 9.0 28.0 72.0 58.0 1.0 1.0 39:55 942:36 28 52.84 12.5 1.0 0.0 1.0 3.0 197:05 39.0 -12.0 25.0 1476.0 13:39 02:51 00:34
2 1504:25 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 68 NaN NaN NaN 22:07 NaN NaN NaN P.K. Subban 11.0 7.0 79.0 151.0 88.0 2.0 6.0 160:14 1232:41 79 0.00 4.6 3.0 0.0 0.0 0.0 111:30 90.0 -21.0 18.0 1883.0 18:07 01:38 02:21
3 1112:11 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 65 NaN NaN NaN 17:06 NaN NaN NaN Kyle Palmieri 20.0 25.0 41.0 155.0 74.0 11.0 18.0 206:17 891:54 41 32.43 16.1 3.0 1.0 0.0 0.0 14:00 36.0 -4.0 45.0 1374.0 13:43 00:12 03:10
4 1020:59 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 51 NaN NaN NaN 20:01 NaN NaN NaN Dmitry Kulikov 8.0 2.0 32.0 54.0 104.0 0.0 0.0 06:20 944:51 32 0.00 3.7 1.0 0.0 0.0 0.0 69:48 77.0 -4.0 10.0 1241.0 18:31 01:22 00:07
5 538:48 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 27 NaN NaN NaN 19:57 NaN NaN NaN Ryan Murray 7.0 2.0 4.0 32.0 12.0 0.0 2.0 23:15 460:25 4 0.00 6.3 0.0 0.0 0.0 0.0 55:08 50.0 -9.0 9.0 708.0 17:03 02:02 00:51
6 1584:26 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 69 NaN NaN NaN 22:57 NaN NaN NaN Damon Severson 23.0 8.0 52.0 114.0 81.0 3.0 10.0 137:22 1277:50 52 0.00 7.0 2.0 0.0 0.0 0.0 169:14 97.0 -20.0 31.0 1924.0 18:31 02:27 01:59
7 417:53 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 29 NaN NaN NaN 14:24 NaN NaN NaN Connor Carrick 5.0 1.0 17.0 25.0 27.0 0.0 0.0 02:29 402:01 17 0.00 4.0 1.0 0.0 0.0 0.0 13:23 39.0 -6.0 6.0 564.0 13:51 00:27 00:05
8 969:45 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 66 NaN NaN NaN 14:41 NaN NaN NaN Nikita Gusev 31.0 13.0 12.0 158.0 12.0 5.0 15.0 164:10 805:25 12 33.33 8.2 2.0 0.0 0.0 0.0 00:10 7.0 -15.0 44.0 1173.0 12:12 00:00 02:29
9 677:27 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 43 NaN NaN NaN 15:45 NaN NaN NaN Andreas Johnsson 13.0 8.0 14.0 78.0 43.0 4.0 5.0 86:53 581:07 14 0.00 10.3 1.0 0.0 0.0 0.0 09:27 21.0 0.0 21.0 897.0 13:30 00:13 02:01
10 1003:22 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 56 NaN NaN NaN 17:55 NaN NaN NaN Will Butcher 17.0 4.0 6.0 62.0 31.0 0.0 1.0 72:35 918:16 6 0.00 6.5 1.0 0.0 0.0 0.0 12:31 75.0 -8.0 21.0 1269.0 16:23 00:13 01:17
11 899:52 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 68 NaN NaN NaN 13:14 NaN NaN NaN Miles Wood 12.0 11.0 57.0 141.0 102.0 0.0 0.0 53:47 841:58 57 0.00 7.8 1.0 0.0 0.0 0.0 04:07 26.0 -19.0 23.0 1169.0 12:22 00:03 00:47
12 1057:23 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 65 NaN NaN NaN 16:16 NaN NaN NaN Pavel Zacha 24.0 8.0 14.0 97.0 62.0 3.0 8.0 106:40 818:37 14 43.27 8.2 1.0 0.0 2.0 4.0 132:06 19.0 -12.0 32.0 1343.0 12:35 02:01 01:38
13 2684:01 8.0 3.0 0.0 22.0 14.0 1328.0 160.0 36.0 1132.0 42.0 1225.0 185.0 0.915 2.7720 47 43.0 1452.0 124.0 57:06 86.486486 85.714286 92.408163 Mackenzie Blackwood NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
14 838:58 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 60 NaN NaN NaN 13:58 NaN NaN NaN Jesper Bratt 16.0 16.0 6.0 101.0 29.0 1.0 6.0 120:47 716:17 6 23.07 15.8 2.0 0.0 0.0 0.0 01:54 22.0 -6.0 32.0 1096.0 11:56 00:01 02:00
15 122:45 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 12 NaN NaN NaN 10:13 NaN NaN NaN Michael McLeod 2.0 0.0 4.0 11.0 19.0 0.0 0.0 00:12 120:51 4 50.00 0.0 0.0 0.0 0.0 0.0 01:42 6.0 4.0 2.0 158.0 10:04 00:08 00:01
16 1047:32 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 58 NaN NaN NaN 18:03 NaN NaN NaN Nico Hischier 22.0 14.0 12.0 123.0 48.0 2.0 10.0 155:56 838:15 12 51.73 11.4 1.0 0.0 1.0 2.0 53:21 37.0 -16.0 36.0 1278.0 14:27 00:55 02:41
17 967:47 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 61 NaN NaN NaN 15:51 NaN NaN NaN Jack Hughes 14.0 7.0 10.0 123.0 12.0 4.0 9.0 193:42 772:59 10 36.14 5.7 2.0 1.0 0.0 0.0 01:06 21.0 -26.0 21.0 1104.0 12:40 00:01 03:10
18 1523:44 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 68 NaN NaN NaN 22:24 NaN NaN NaN Ryan Pulock 25.0 10.0 14.0 163.0 110.0 3.0 8.0 120:08 1302:12 14 0.00 6.1 3.0 1.0 0.0 0.0 101:24 139.0 8.0 35.0 1788.0 19:09 01:29 01:46
19 1106:16 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 64 NaN NaN NaN 17:17 NaN NaN NaN Johnny Boychuk 9.0 2.0 14.0 96.0 135.0 1.0 1.0 05:24 968:51 14 0.00 2.1 0.0 0.0 0.0 0.0 132:01 128.0 -11.0 11.0 1420.0 15:08 02:03 00:05

Related

How to convert multiple set of column to single column in pandas?

i want to convert a columns(Azi_0 to Azi_47,Dist_0 to Dist_47) in dataframe(df) to a two column(Azimuth,Distance) as in new_df?
Azi = [f"Azi_{i}" for i in range(47)]
dist = [f"Dist_{i}" for i in range(47)]
sample dataframe,df:
expected output,new_df:
Current_Sim_Az_obj1
Current_Sim_distance_r_obj1
Azimuth
Distance
-60
3.950372041
-59.73007665
3.07
-60
3.950372041
-59.73007665
3.07
-60
6.950372041
-59.4701257
7.89
-60
6.950372041
-59.89004647
7.765
-60
8.950372041
-59.64009363
8.345
-60
8.950372041
-59.58010495
8.425
-60
8.950372041
-59.58010495
8.425
-55
2.38397709
-55.06095763
3.14
-55
2.38397709
-55.21092934
3.065
-55
2.38397709
-55.21092934
3.065
-55
2.38397709
-55.2609199
3.03
-55
2.38397709
-55.2609199
3.03
-55
2.38397709
-55.2609199
3.03
-55
2.38397709
-55.2609199
3.03
-55
2.38397709
-55.03096329
3.105
-55
2.38397709
-55.03096329
3.105
-55
2.38397709
-55.32090858
3
-55
2.38397709
-55.32090858
3
-55
2.38397709
-55.27091802
3.12
-55
2.38397709
-55.27091802
3.12
-55
2.38397709
-55.8508086
3.09
-55
2.38397709
-55.8508086
3.09
-55
2.38397709
-55.57086142
3.065
-55
2.38397709
-55.57086142
3.065
How to combine several columns to a single column?
You are essentially asking how to coalesce a values of certain df-columns into one column - you can do it like this:
from random import choice
import pandas as pd
# all azimuth names
azi_names = [f"Azi_{i}" for i in range(5)]
# all distance names
dist_names = [f"Dist_{i}" for i in range(5)]
df = pd.DataFrame(columns = azi_names + dist_names)
# put some values in
for i in range(20):
k = choice(range(5))
df = df.append({f"Azi_{k}": i, f"Dist_{k}": i}, ignore_index=True)
print(df)
which randomly creates:
Azi_0 Azi_1 Azi_2 Azi_3 Azi_4 Dist_0 Dist_1 Dist_2 Dist_3 Dist_4
0 NaN NaN NaN 0.0 NaN NaN NaN NaN 0.0 NaN
1 NaN 1.0 NaN NaN NaN NaN 1.0 NaN NaN NaN
2 2.0 NaN NaN NaN NaN 2.0 NaN NaN NaN NaN
3 NaN NaN 3.0 NaN NaN NaN NaN 3.0 NaN NaN
4 NaN 4.0 NaN NaN NaN NaN 4.0 NaN NaN NaN
5 NaN NaN NaN NaN 5.0 NaN NaN NaN NaN 5.0
6 6.0 NaN NaN NaN NaN 6.0 NaN NaN NaN NaN
7 NaN 7.0 NaN NaN NaN NaN 7.0 NaN NaN NaN
8 NaN 8.0 NaN NaN NaN NaN 8.0 NaN NaN NaN
9 9.0 NaN NaN NaN NaN 9.0 NaN NaN NaN NaN
10 NaN NaN 10.0 NaN NaN NaN NaN 10.0 NaN NaN
11 11.0 NaN NaN NaN NaN 11.0 NaN NaN NaN NaN
12 12.0 NaN NaN NaN NaN 12.0 NaN NaN NaN NaN
13 NaN NaN 13.0 NaN NaN NaN NaN 13.0 NaN NaN
14 NaN 14.0 NaN NaN NaN NaN 14.0 NaN NaN NaN
15 NaN NaN NaN 15.0 NaN NaN NaN NaN 15.0 NaN
16 NaN NaN NaN NaN 16.0 NaN NaN NaN NaN 16.0
17 NaN NaN 17.0 NaN NaN NaN NaN 17.0 NaN NaN
18 NaN NaN NaN NaN 18.0 NaN NaN NaN NaN 18.0
19 NaN NaN NaN 19.0 NaN NaN NaN NaN 19.0 NaN
To coalesce this and only keep filled values you use
df2 = pd.DataFrame()
# propagates values and chooses first
df2["AZI"] = df[azi_names].bfill(axis=1).iloc[:, 0]
df2["DIS"] = df[dist_names].bfill(axis=1).iloc[:, 0]
print(df2)
to get a coalesced new df:
AZI DIS
0 0.0 0.0
1 1.0 1.0
2 2.0 2.0
3 3.0 3.0
4 4.0 4.0
5 5.0 5.0
6 6.0 6.0
7 7.0 7.0
8 8.0 8.0
9 9.0 9.0
10 10.0 10.0
11 11.0 11.0
12 12.0 12.0
13 13.0 13.0
14 14.0 14.0
15 15.0 15.0
16 16.0 16.0
17 17.0 17.0
18 18.0 18.0
19 19.0 19.0
Attributation: inspired by Erfan's answer to Coalesce values from 2 columns into a single column in a pandas dataframe
You may need to Replacing blank values (white space) with NaN in pandas for your shown data.

Is it possible to move each row to end of same row after removing NaN of each row

I've been looking for the way to remove NaN in each row of dfA(DataFrame) and after then, move every row under push1_start_date and reconnect with the end of push1_start_date. Is it possible to do that ?? I tried stack() and unstack() method but it doesn't work .Thank you.
push1_start_date push2_start_date push3_start_date push4_start_date push5_start_date push6_start_date push7_start_date push8_start_date
2021-04-29 3 NaN NaN NaN NaN NaN NaN NaN
2021-04-30 20 NaN NaN NaN NaN NaN NaN NaN
2021-05-01 24 NaN NaN NaN NaN NaN NaN NaN
2021-05-02 21 NaN NaN NaN NaN NaN NaN NaN
2021-05-03 14 NaN NaN NaN NaN NaN NaN NaN
2021-05-04 5 NaN NaN NaN NaN NaN NaN NaN
2021-05-05 14 NaN NaN NaN NaN NaN NaN NaN
2021-05-06 16 NaN NaN NaN NaN NaN NaN NaN
2021-05-07 17 NaN NaN NaN NaN NaN NaN NaN
2021-05-08 14 NaN NaN NaN NaN NaN NaN NaN
2021-05-11 78 NaN NaN NaN NaN NaN NaN NaN
2021-05-12 20 78.0 NaN NaN NaN NaN NaN NaN
2021-05-13 13 21.0 NaN NaN NaN NaN NaN NaN
2021-05-14 8 12.0 NaN NaN NaN NaN NaN NaN
2021-05-15 18 8.0 NaN NaN NaN NaN NaN NaN
2021-05-16 16 19.0 NaN NaN NaN NaN NaN NaN
2021-05-17 16 16.0 NaN NaN NaN NaN NaN NaN
2021-05-18 18 15.0 NaN NaN NaN NaN NaN NaN
2021-05-19 14 19.0 NaN NaN 1.0 2.0 NaN NaN
2021-05-20 13 14.0 1.0 NaN 1.0 1.0 NaN NaN
2021-05-21 11 13.0 NaN NaN 1.0 NaN 1.0 NaN
2021-05-22 26 10.0 NaN 2.0 NaN 1.0 NaN NaN
2021-05-23 12 27.0 NaN 1.0 NaN NaN NaN NaN
2021-05-24 15 12.0 1.0 3.0 NaN 1.0 NaN NaN
2021-05-25 9 16.0 NaN 1.0 NaN 1.0 NaN NaN
2021-05-26 14 9.0 NaN 1.0 NaN NaN NaN NaN
2021-05-27 14 12.0 NaN NaN NaN NaN NaN NaN
2021-05-28 21 16.0 NaN NaN NaN NaN NaN NaN
2021-05-29 23 20.0 1.0 2.0 1.0 1.0 NaN NaN
2021-05-30 18 23.0 1.0 NaN 1.0 1.0 NaN NaN
2021-05-31 19 17.0 NaN 3.0 1.0 3.0 NaN NaN
2021-06-01 15 21.0 NaN 3.0 1.0 1.0 NaN NaN
2021-06-02 22 13.0 1.0 2.0 NaN 1.0 NaN NaN
2021-06-03 19 23.0 1.0 NaN NaN 1.0 NaN NaN
2021-06-04 12 20.0 2.0 NaN 2.0 NaN NaN NaN
2021-06-05 2 1.0 NaN NaN NaN 1.0 NaN NaN
ideal output
push1_start_date
2021-04-29 3 ←The begging of push1_start_date
2021-06-05 2 ←The last of push1_start_date
2021-05-12 78 ←The begging of push2_start_date
2021-06-05 1.0 ←The last of push2_start_date
2021-05-20 1.0 ←The begging of push2_start_date
2021-06-04 2.0 ←The last of push2_start_date
it comtines untill push8_start_date
You can try with reset_index(), melt(),dropna() and drop():
out=(df.reset_index()
.melt('index',value_name='push_start_date')
.dropna(subset=['push_start_date'])
.drop('variable',1))
OR
via concat() and to_frame():
out=(pd.concat([df[x].dropna() for x in df.columns[df.dtypes!='object']])
.to_frame('push_start_date'))
You could use df.melt() to stack all the columns on the right into 1 column, then keep only the value column without null values:
df.melt().drop('variable', axis=1).dropna()
Output
value
2021-04-29 3
... ...
2021-06-05 2
2021-05-12 78
... ...
2021-06-05 1.0
2021-05-20 1.0
... ...
2021-06-04 2.0
... ...

How should I combine the rows of similar time in a Dataframe?

I'm processing a MIMIC dataset. Now I want to combine the data in the rows whose time difference (delta time) is below 10min. How can I do that?
The original data:
charttime hadm_id age is_male HR RR SPO2 Systolic_BP Diastolic_BP MAP PEEP PO2
0 2119-07-20 17:54:00 26270240 NaN NaN NaN NaN NaN 103.0 66.0 81.0 NaN NaN
1 2119-07-20 17:55:00 26270240 68.0 1.0 113.0 26.0 NaN NaN NaN NaN NaN NaN
2 2119-07-20 17:57:00 26270240 NaN NaN NaN NaN 92.0 NaN NaN NaN NaN NaN
3 2119-07-20 18:00:00 26270240 68.0 1.0 114.0 28.0 NaN 85.0 45.0 62.0 16.0 NaN
4 2119-07-20 18:01:00 26270240 NaN NaN NaN NaN 91.0 NaN NaN NaN NaN NaN
5 2119-07-30 21:00:00 26270240 68.0 1.0 90.0 16.0 93.0 NaN NaN NaN NaN NaN
6 2119-07-30 21:00:00 26270240 68.0 1.0 89.0 9.0 94.0 NaN NaN NaN NaN NaN
7 2119-07-30 21:01:00 26270240 68.0 1.0 89.0 10.0 93.0 NaN NaN NaN NaN NaN
8 2119-07-30 21:05:00 26270240 NaN NaN NaN NaN NaN 109.0 42.0 56.0 NaN NaN
9 2119-07-30 21:10:00 26270240 68.0 1.0 90.0 10.0 93.0 NaN NaN NaN NaN NaN
After combining the rows whose delta time is less than 10 min, the output I want:
(when there is duplicate data in same column in some rows to group, just take the first one)
charttime hadm_id age is_male HR RR SPO2 Systolic_BP Diastolic_BP MAP PEEP PO2
0 2119-07-20 17:55:00 26270240 68.0 1.0 113.0 26.0 92.0 103.0 66.0 81.0 16.0 NaN2119-07-30 20:00:00 26270240 68.0 1.0 90.0 16.0 93.0 NaN NaN NaN NaN NaN
1 2119-07-30 21:00:00 26270240 68.0 1.0 89.0 9.0 94.0 109.0 42.0 56.0 NaN NaN
How can I do this?
First, I would round the timestamp column to 10 minutes:
df['charttime'] = pd.to_datetime(df['charttime']).dt.floor('10T').dt.time
Then, I would drop the duplicates, based on the columns you want to compare (for example, hadm_id and charttime:
df.drop_duplicates(subset=['charttime', 'hadm_id'], keep='first', inplace=True)

why does df.diff give me NaN in the 4 th column?

I have the following code:
# create dataframes for the lists of arrays (df_Avg_R), list of maxima
# (df_peaks) and for the inter-beat-intervals (df_ibi)
df_Avg_R = pd.DataFrame(Avg_R_val)
df_idx_max = pd.DataFrame(idx_of_max)
# delete first and last maxima
df_idx_max.drop([0, 11], axis=1, inplace=1)
df_ibi = df_idx_max.diff(axis=1)
df_idx_max is the following dataframe (only the first rows):
1 2 3 4 5 6 7 8 9 10
0 55 92 132 181.0 218.0 251.0 NaN NaN NaN NaN
1 84 140 198 235.0 251.0 NaN NaN NaN NaN NaN
2 47 64 103 123.0 185.0 251.0 NaN NaN NaN NaN
3 58 102 146 189.0 251.0 NaN NaN NaN NaN NaN
4 53 96 139 182.0 201.0 225.0 251.0 NaN NaN NaN
5 46 89 131 173.0 215.0 251.0 NaN NaN NaN NaN
6 67 121 161 175.0 231.0 251.0 NaN NaN NaN NaN
7 52 109 165 206.0 220.0 251.0 NaN NaN NaN NaN
8 80 135 191 251.0 NaN NaN NaN NaN NaN NaN
9 38 83 139 188.0 251.0 NaN NaN NaN NaN NaN
10 33 73 113 161.0 205.0 251.0 NaN NaN NaN NaN
11 54 81 126 153.0 180.0 204.0 251.0 NaN NaN NaN
12 44 64 116 160.0 206.0 251.0 NaN NaN NaN NaN
13 56 109 165 220.0 251.0 NaN NaN NaN NaN NaN
14 43 100 124 155.0 211.0 251.0 NaN NaN NaN NaN
however the command df_ibi = df_idx_max.diff(axis=1) gives me NaN in all the
4th column of the df_ibi
1 2 3 4 5 6 7 8 9 10
0 NaN 37.0 40.0 NaN 37.0 33.0 NaN NaN NaN NaN
1 NaN 56.0 58.0 NaN 16.0 NaN NaN NaN NaN NaN
2 NaN 17.0 39.0 NaN 62.0 66.0 NaN NaN NaN NaN
3 NaN 44.0 44.0 NaN 62.0 NaN NaN NaN NaN NaN
4 NaN 43.0 43.0 NaN 19.0 24.0 26.0 NaN NaN NaN
5 NaN 43.0 42.0 NaN 42.0 36.0 NaN NaN NaN NaN
6 NaN 54.0 40.0 NaN 56.0 20.0 NaN NaN NaN NaN
7 NaN 57.0 56.0 NaN 14.0 31.0 NaN NaN NaN NaN
8 NaN 55.0 56.0 NaN NaN NaN NaN NaN NaN NaN
9 NaN 45.0 56.0 NaN 63.0 NaN NaN NaN NaN NaN
10 NaN 40.0 40.0 NaN 44.0 46.0 NaN NaN NaN NaN
11 NaN 27.0 45.0 NaN 27.0 24.0 47.0 NaN NaN NaN
12 NaN 20.0 52.0 NaN 46.0 45.0 NaN NaN NaN NaN
13 NaN 53.0 56.0 NaN 31.0 NaN NaN NaN NaN NaN
14 NaN 57.0 24.0 NaN 56.0 40.0 NaN NaN NaN NaN
Do you know why this happens? Thanks
If you convert your entire dataframe to floats, it should work without a problem:
df_idx_max = df_idx_max.astype(float, errors='ignore')
df_ibi = df_idx_max.diff(axis=1)
I think it is something like a bug, look at this issue. You can use the following code to temporarily overcome this problem:
df.T.diff().T
With your data should be:
df_idx_max.T.diff().T
Let me know if it works.

pandas interpolate doesnt fill null values

i have this code which I load a my data to a dataframe and i try to fill up the naN values using .interpolate instead of replacing it with 0
my dataframe looks like this:
weight height wc hc FBS HBA1C
0 NaN NaN NaN NaN NaN NaN
1 55.6 151.0 NaN NaN 126.0 NaN
2 42.8 151.0 73.0 79.0 NaN NaN
3 60.8 155.0 NaN NaN 201.0 NaN
4 NaN NaN NaN NaN NaN NaN
5 60.0 NaN 87.0 92.0 NaN NaN
6 NaN NaN NaN NaN NaN NaN
7 NaN NaN NaN NaN NaN NaN
8 NaN NaN NaN NaN 194.0 NaN
9 57.0 158.0 95.0 90.0 NaN NaN
10 46.0 NaN 83.0 91.0 223.0 NaN
11 NaN NaN NaN NaN NaN NaN
12 NaN NaN NaN NaN NaN NaN
13 58.5 164.0 NaN NaN NaN NaN
14 62.0 154.0 80.5 100.0 NaN NaN
15 NaN NaN NaN NaN NaN NaN
16 57.0 152.0 NaN NaN NaN NaN
17 62.4 153.0 88.0 99.0 NaN NaN
18 NaN NaN NaN NaN NaN NaN
19 48.0 146.0 NaN NaN NaN NaN
20 68.7 NaN NaN NaN NaN NaN
21 49.0 146.0 NaN NaN NaN NaN
22 NaN NaN NaN NaN NaN NaN
23 NaN NaN NaN NaN NaN NaN
24 70.2 161.0 NaN NaN NaN NaN
25 70.4 161.0 93.0 68.0 NaN NaN
26 61.8 143.0 91.0 98.0 NaN NaN
27 70.4 NaN NaN NaN NaN NaN
28 70.1 144.0 100.0 103.0 NaN NaN
29 NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ...
318 49.0 146.0 92.0 89.0 NaN NaN
319 64.7 145.0 87.0 107.0 NaN NaN
320 55.5 149.0 81.0 101.0 NaN NaN
321 55.4 145.0 87.0 96.0 NaN NaN
322 53.1 153.0 83.0 96.0 NaN NaN
323 52.1 147.0 89.0 92.0 NaN NaN
324 68.9 167.0 96.0 100.0 NaN NaN
325 NaN NaN NaN NaN NaN NaN
326 57.0 142.0 100.0 101.0 NaN NaN
327 72.5 163.0 98.0 95.0 NaN NaN
328 73.5 157.0 94.0 114.0 NaN NaN
329 61.0 160.0 90.0 89.5 NaN NaN
330 49.0 150.0 80.0 90.0 NaN NaN
331 50.0 150.0 83.0 90.0 NaN NaN
332 67.6 155.0 92.0 103.0 NaN NaN
333 NaN NaN NaN NaN NaN NaN
334 78.7 162.0 99.0 101.0 NaN NaN
335 74.5 155.0 98.0 110.0 NaN NaN
336 68.0 152.0 85.0 93.0 NaN NaN
337 67.0 152.0 NaN NaN 179.1 NaN
338 NaN NaN NaN NaN 315.0 NaN
339 38.0 145.0 66.0 NaN 196.0 NaN
340 50.0 148.0 NaN NaN 133.0 NaN
341 73.5 NaN NaN NaN NaN NaN
342 74.5 NaN NaN NaN NaN NaN
343 NaN NaN NaN NaN NaN NaN
344 67.0 152.0 106.0 NaN NaN NaN
345 52.0 145.0 94.0 NaN NaN NaN
346 52.0 159.0 89.0 NaN NaN NaN
347 67.0 153.0 92.0 91.0 NaN NaN
my code:
import pandas as pd
df = pd.read_csv('final_dataset_3.csv')
import numpy as np
df['weight'].replace(0,np.nan, inplace=True)
df['height'].replace(0,np.nan, inplace=True)
df['wc'].replace(0,np.nan, inplace=True)
df['hc'].replace(0,np.nan, inplace=True)
df['FBS'].replace(0,np.nan, inplace=True)
df['HBA1C'].replace(0,np.nan, inplace=True)
df1 = df.interpolate()
df1
df1 looks like this
weight height wc hc FBS HBA1C
0 NaN NaN NaN NaN NaN NaN
1 55.600000 151.0 NaN NaN 126.000000 NaN
2 42.800000 151.0 73.000000 79.000000 163.500000 NaN
3 60.800000 155.0 77.666667 83.333333 201.000000 NaN
4 60.400000 155.5 82.333333 87.666667 199.600000 NaN
5 60.000000 156.0 87.000000 92.000000 198.200000 NaN
6 59.250000 156.5 89.000000 91.500000 196.800000 NaN
after running the code, it didnt replace the naN values with a value instead replaces the values with more decimal points.
Looking at this data leads me to believe that interpolating the values would be improper. Each row represents some attributes for different people. You cannot base a missing value of, say, weight on adjacent rows. I understand that you need to deal with the NaN's because much of the data will be useless when building many types of models.
Instead maybe you should fill with the mean() or median(). Here's a simple dataframe with some missing values.
df
Out[58]:
height weight
0 54.0 113.0
1 61.0 133.0
2 NaN 129.0
3 48.0 NaN
4 60.0 107.0
5 51.0 114.0
6 NaN 165.0
7 51.0 NaN
8 53.0 147.0
9 NaN 124.0
To replace missing values with the mean() of the column:
df.fillna(df.mean())
Out[59]:
height weight
0 54.0 113.0
1 61.0 133.0
2 54.0 129.0
3 48.0 129.0
4 60.0 107.0
5 51.0 114.0
6 54.0 165.0
7 51.0 129.0
8 53.0 147.0
9 54.0 124.0
Of course, you could easily use median() or some other method that makes sense for your data.

Categories

Resources