I have a block in the processing of missing data
i have this df
index a b c del
2018-06-25 12:51:00 NaN NaN NaN 1
2018-06-25 12:52:00 NaN NaN NaN NaN
2018-06-25 12:53:00 NaN NaN NaN NaN
2018-06-25 12:54:00 NaN NaN NaN NaN
2018-06-25 12:55:00 NaN NaN NaN NaN
2018-06-25 12:56:00 NaN NaN NaN NaN
2018-06-25 12:57:00 NaN NaN NaN NaN
2018-06-25 12:58:00 0.5 0.6 0.6 0.0
2018-06-25 12:59:00 NaN NaN NaN 0.0
2018-06-25 13:00:00 0.6 0.8 0.6 0.0
2018-06-25 13:01:00 NaN NaN NaN 0.0
2018-06-25 13:02:00 0.6 0.9 0.6 0.0
what I want to do
interpolate missing values if the value of del is not missing
i have this solution keep just the df when del has a value and I do my interpolation after I concatene
but I want to avoid concatenation and too much line of code and variables
dfs= df.loc[df['del'].notnull(),:]
dfs.interpolate(method='time')
dfs1= df.loc[df['del'].isnull(),:]
dfs= pd.concat([dfs,dfs1], axis=1, sort=True, join_axes=[df.index])
desired output :
index a b c del
2018-06-25 12:51:00 NaN NaN NaN 1.0
2018-06-25 12:52:00 NaN NaN NaN NaN
2018-06-25 12:53:00 NaN NaN NaN NaN
2018-06-25 12:54:00 NaN NaN NaN NaN
2018-06-25 12:55:00 NaN NaN NaN NaN
2018-06-25 12:56:00 NaN NaN NaN NaN
2018-06-25 12:57:00 NaN NaN NaN NaN
2018-06-25 12:58:00 0.5 0.6 0.6 0.0
2018-06-25 12:59:00 0.6 0.7 0.7 0.0
2018-06-25 13:00:00 0.6 0.8 0.6 0.0
2018-06-25 13:01:00 0.7 0.9 0.7 0.0
2018-06-25 13:02:00 0.6 0.9 0.6 0.0
story of just closing the little hole by column
Thank you <<
Use .loc to assign the interpolation only where 'del' is not null:
df.loc[df['del'].notnull()] = df.loc[df['del'].notnull()].interpolate(method='time')
a b c del
2018-06-25 12:51:00 NaN NaN NaN 1.0
2018-06-25 12:52:00 NaN NaN NaN NaN
2018-06-25 12:53:00 NaN NaN NaN NaN
2018-06-25 12:54:00 NaN NaN NaN NaN
2018-06-25 12:55:00 NaN NaN NaN NaN
2018-06-25 12:56:00 NaN NaN NaN NaN
2018-06-25 12:57:00 NaN NaN NaN NaN
2018-06-25 12:58:00 0.50 0.60 0.6 0.0
2018-06-25 12:59:00 0.55 0.70 0.6 0.0
2018-06-25 13:00:00 0.60 0.80 0.6 0.0
2018-06-25 13:01:00 0.60 0.85 0.6 0.0
2018-06-25 13:02:00 0.60 0.90 0.6 0.0
Related
This is the site I'm trying to retrieve information from: https://www.baseball-reference.com/boxes/CLE/CLE202108120.shtml I want to get the box score data so like the Oakland A's total batting average in the game, at bats in the game, etc. However, when I retreive and print the html from the site, these box scores are missing completely from the html. Any suggestions? Thanks.
Here's my code:
from bs4 import BeautifulSoup
import requests
url = "https://www.baseball-reference.com/boxes/CLE/CLE202108120.shtml"
page = requests.get(url)
soup = BeautifulSoup(page.content, 'html.parser')
print(soup.prettify)
Please help! Thanks! I tried selenium and had the same problem.
The page is loaded by javascript. Try using the requests_html package instead. See below sample.
from bs4 import BeautifulSoup
from requests_html import HTMLSession
url = "https://www.baseball-reference.com/boxes/CLE/CLE202108120.shtml"
s = HTMLSession()
page = s.get(url, timeout=20)
page.html.render()
soup = BeautifulSoup(page.html.html, 'html.parser')
print(soup.prettify)
The other tables are there in the requested html, but within the comments. So you need to parse out the comments to get those additional tables:
import requests
from bs4 import BeautifulSoup, Comment
import pandas as pd
url = "https://www.baseball-reference.com/boxes/CLE/CLE202108120.shtml"
result = requests.get(url).text
data = BeautifulSoup(result, 'html.parser')
comments = data.find_all(string=lambda text: isinstance(text, Comment))
tables = pd.read_html(url)
for each in comments:
if 'table' in str(each):
try:
tables.append(pd.read_html(str(each))[0])
except:
continue
Output:
Oakland
print(tables[2].to_string())
Batting AB R H RBI BB SO PA BA OBP SLG OPS Pit Str WPA aLI WPA+ WPA- cWPA acLI RE24 PO A Details
0 Mark Canha LF 6.0 1.0 1.0 3.0 0.0 0.0 6.0 0.247 0.379 0.415 0.793 23.0 19.0 0.011 0.58 0.040 -0.029% 0.01% 1.02 1.0 1.0 0.0 2B
1 Starling Marte CF 3.0 0.0 2.0 3.0 0.0 1.0 4.0 0.325 0.414 0.476 0.889 12.0 7.0 0.116 0.90 0.132 -0.016% 0.12% 1.57 2.8 1.0 0.0 2B,HBP
2 Stephen Piscotty PH-RF 1.0 0.0 1.0 2.0 0.0 0.0 2.0 0.211 0.272 0.349 0.622 7.0 3.0 0.000 0.00 0.000 0.000% 0% 0.00 2.0 1.0 0.0 HBP
3 Matt Olson 1B 6.0 0.0 1.0 2.0 0.0 0.0 6.0 0.283 0.376 0.566 0.941 21.0 13.0 -0.057 0.45 0.008 -0.065% -0.06% 0.78 -0.6 9.0 1.0 GDP
4 Mitch Moreland DH 5.0 3.0 2.0 2.0 0.0 0.0 6.0 0.230 0.290 0.415 0.705 23.0 16.0 0.049 0.28 0.064 -0.015% 0.05% 0.50 1.5 NaN NaN 2·HR,HBP
5 Josh Harrison 2B 0.0 1.0 0.0 0.0 1.0 0.0 1.0 0.294 0.366 0.435 0.801 7.0 3.0 0.057 1.50 0.057 0.000% 0.06% 2.63 0.6 0.0 0.0 NaN
6 Tony Kemp 2B 4.0 3.0 3.0 0.0 1.0 0.0 5.0 0.252 0.370 0.381 0.751 16.0 10.0 -0.001 0.14 0.009 -0.010% 0% 0.24 1.6 2.0 2.0 NaN
7 Sean Murphy C 4.0 3.0 2.0 2.0 2.0 1.0 6.0 0.224 0.318 0.419 0.737 25.0 15.0 0.143 0.38 0.151 -0.007% 0.15% 0.67 2.7 7.0 0.0 2B
8 Matt Chapman 3B 1.0 3.0 0.0 0.0 5.0 1.0 6.0 0.214 0.310 0.365 0.676 31.0 10.0 0.051 0.28 0.051 0.000% 0.05% 0.49 2.2 1.0 3.0 NaN
9 Seth Brown RF-CF 5.0 1.0 1.0 1.0 0.0 1.0 6.0 0.204 0.278 0.451 0.730 18.0 12.0 -0.067 0.40 0.000 -0.067% -0.07% 0.70 -1.7 4.0 0.0 SF
10 Elvis Andrus SS 5.0 2.0 1.0 2.0 1.0 0.0 6.0 0.233 0.283 0.310 0.593 20.0 15.0 0.015 0.42 0.050 -0.034% 0.02% 0.73 -0.1 0.0 4.0 NaN
11 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
12 Chris Bassitt P NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1.0 0.0 NaN
13 A.J. Puk P NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0.0 0.0 NaN
14 Deolis Guerra P NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0.0 0.0 NaN
15 Jake Diekman P NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0.0 0.0 NaN
16 Team Totals 40.0 17.0 14.0 17.0 10.0 4.0 54.0 0.350 0.500 0.575 1.075 203.0 123.0 0.317 0.41 0.562 -0.243% 0.33% 0.72 12.2 27.0 10.0 NaN
My dataset has 12 columns, X1-X6 and Y1-Y6. The variables X and Y match to each other - the first record means: 80 parts of A, 10 parts of C, 2 parts of J and 8 parts of K (each row has 100 total).
I would like to be able to transform my dataset into a dataset in which the entries in columns X1-X6 are now the headers. See before and after datasets below.
My dataset (before):
X1 X2 X3 X4 X5 X6 Y1 Y2 Y3 Y4 Y5 Y6
0 A C J K NaN NaN 80.0 10.0 2.0 8.0 NaN NaN
1 F N O NaN NaN NaN 2.0 25.0 73.0 NaN NaN NaN
2 A H J M NaN NaN 70.0 6.0 15.0 9.0 NaN NaN
3 B I K P NaN NaN 0.5 1.5 2.0 96.0 NaN NaN
4 A B F H O P 83.0 4.0 9.0 2.0 1.0 1.0
5 A B F G NaN NaN 1.0 16.0 9.0 74.0 NaN NaN
6 A B D F L NaN 95.0 2.0 1.0 1.0 1.0 NaN
7 B F H P NaN NaN 0.2 0.4 0.4 99.0 NaN NaN
8 A D F L NaN NaN 35.0 12.0 30.0 23.0 NaN NaN
9 A B F I O NaN 95.0 0.3 0.1 1.6 3.0 NaN
10 B E G NaN NaN NaN 10.0 31.0 59.0 NaN NaN NaN
11 A F G L NaN NaN 24.0 6.0 67.0 3.0 NaN NaN
12 A C I NaN NaN NaN 65.0 30.0 5.0 NaN NaN NaN
13 A F G L NaN NaN 55.0 6.0 4.0 35.0 NaN NaN
14 A F J K L NaN 22.0 3.0 12.0 0.8 62.2 NaN
15 B F I P NaN NaN 0.6 1.2 0.2 98.0 NaN NaN
16 A B F H O NaN 27.0 6.0 46.0 13.0 8.0 NaN
The dataset I'd like to transform to:
A B C D E F G H I J K L M \
0 80.0 NaN 10.0 NaN NaN NaN NaN NaN NaN 2.0 8.0 NaN NaN
1 NaN NaN NaN NaN NaN 2.0 NaN NaN NaN NaN NaN NaN NaN
2 70.0 NaN NaN NaN NaN NaN NaN 6.0 NaN 15.0 NaN NaN 9.0
3 NaN 0.5 NaN NaN NaN NaN NaN NaN 1.5 NaN 2.0 NaN NaN
4 83.0 4.0 NaN NaN NaN 9.0 NaN 2.0 NaN NaN NaN NaN NaN
5 1.0 16.0 NaN NaN NaN 9.0 74.0 NaN NaN NaN NaN NaN NaN
6 95.0 2.0 NaN 1.0 NaN 1.0 NaN NaN NaN NaN NaN 1.0 NaN
7 NaN 0.2 NaN NaN NaN 0.4 NaN 0.4 NaN NaN NaN NaN NaN
8 35.0 NaN NaN 12.0 NaN 30.0 NaN NaN NaN NaN NaN 23.0 NaN
9 95.0 0.3 NaN NaN NaN 0.1 NaN NaN 1.6 NaN NaN NaN NaN
10 NaN 10.0 NaN NaN 31.0 NaN 59.0 NaN NaN NaN NaN NaN NaN
11 24.0 NaN NaN NaN NaN 6.0 67.0 NaN NaN NaN NaN 3.0 NaN
12 65.0 NaN 30.0 NaN NaN NaN NaN NaN 5.0 NaN NaN NaN NaN
13 55.0 NaN NaN NaN NaN 6.0 4.0 NaN NaN NaN NaN 35.0 NaN
14 22.0 NaN NaN NaN NaN 3.0 NaN NaN NaN 12.0 0.8 62.2 NaN
15 NaN 0.6 NaN NaN NaN 1.2 NaN NaN 0.2 NaN NaN NaN NaN
16 27.0 6.0 NaN NaN NaN 46.0 NaN 13.0 NaN NaN NaN NaN NaN
N O P
0 NaN NaN NaN
1 25.0 73.0 NaN
2 NaN NaN NaN
3 NaN NaN 96.0
4 NaN 1.0 1.0
5 NaN NaN NaN
6 NaN NaN NaN
7 NaN NaN 99.0
8 NaN NaN NaN
9 NaN 3.0 NaN
10 NaN NaN NaN
11 NaN NaN NaN
12 NaN NaN NaN
13 NaN NaN NaN
14 NaN NaN NaN
15 NaN NaN 98.0
16 NaN 8.0 NaN
As you know that you want the Xi part to contain the column names for the new dataframe, while the Yi part would be the value, it is enough to change every line in a dict where Xi is the key and Yi the value. Then you use the list of that dictionnaries to feed the new dataframe:
data = list(df.apply(lambda x: {x['X'+ str(i)]: x['Y'+str(i)] for i in range(1,7)
if x['X'+str(i)]!= 'NaN'}, axis=1))
resul = pd.DataFrame(data)
print(resul)
gives:
A B C D E F ... K L M N O P
0 80.0 NaN 10.0 NaN NaN NaN ... 8.0 NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN 2.0 ... NaN NaN NaN 25.0 73.0 NaN
2 70.0 NaN NaN NaN NaN NaN ... NaN NaN 9.0 NaN NaN NaN
3 NaN 0.5 NaN NaN NaN NaN ... 2.0 NaN NaN NaN NaN 96.0
4 83.0 4.0 NaN NaN NaN 9.0 ... NaN NaN NaN NaN 1.0 1.0
5 1.0 16.0 NaN NaN NaN 9.0 ... NaN NaN NaN NaN NaN NaN
6 95.0 2.0 NaN 1.0 NaN 1.0 ... NaN 1.0 NaN NaN NaN NaN
7 NaN 0.2 NaN NaN NaN 0.4 ... NaN NaN NaN NaN NaN 99.0
8 35.0 NaN NaN 12.0 NaN 30.0 ... NaN 23.0 NaN NaN NaN NaN
9 95.0 0.3 NaN NaN NaN 0.1 ... NaN NaN NaN NaN 3.0 NaN
10 NaN 10.0 NaN NaN 31.0 NaN ... NaN NaN NaN NaN NaN NaN
11 24.0 NaN NaN NaN NaN 6.0 ... NaN 3.0 NaN NaN NaN NaN
12 65.0 NaN 30.0 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN
13 55.0 NaN NaN NaN NaN 6.0 ... NaN 35.0 NaN NaN NaN NaN
14 22.0 NaN NaN NaN NaN 3.0 ... 0.8 62.2 NaN NaN NaN NaN
15 NaN 0.6 NaN NaN NaN 1.2 ... NaN NaN NaN NaN NaN 98.0
16 27.0 6.0 NaN NaN NaN 46.0 ... NaN NaN NaN NaN 8.0 NaN
[17 rows x 16 columns]
One way to handle this. Loop through each row, splitting the dataframe in half using iloc. Then build a new dictionary using zip, then create a resulting dataframe.
df_dict = {x: list(zip(df.iloc[x,0:6], df.iloc[x,6:12])) for x in range(df.shape[0])}
df1 = pd.DataFrame.from_dict(pd_dict, orient='index')
df1.sort_index(1)
A B C F H I J K M N O P nan
0 80.0 NaN 10.0 NaN NaN NaN 2.0 8.0 NaN NaN NaN NaN NaN
1 NaN NaN NaN 2.0 NaN NaN NaN NaN NaN 25.0 73.0 NaN NaN
2 70.0 NaN NaN NaN 6.0 NaN 15.0 NaN 9.0 NaN NaN NaN NaN
3 NaN 0.5 NaN NaN NaN 1.5 NaN 2.0 NaN NaN NaN 96. NaN
4 83.0 4.0 NaN 9.0 2.0 NaN NaN NaN NaN NaN 1.0 1.0 NaN
This question already has answers here:
Replace NaN or missing values with rolling mean or other interpolation
(2 answers)
Python: Sliding windowed mean, ignoring missing data
(2 answers)
Closed 4 years ago.
I have a df like this:
a001 a002 a003 a004 a005
time_axis
2017-02-07 1 NaN NaN NaN NaN
2017-02-14 NaN NaN NaN NaN NaN
2017-03-20 NaN NaN 2 NaN NaN
2017-04-03 NaN 3 NaN NaN NaN
2017-05-15 NaN NaN NaN NaN NaN
2017-06-05 NaN NaN NaN NaN NaN
2017-07-10 NaN 6 NaN NaN NaN
2017-07-17 4 NaN NaN NaN NaN
2017-07-24 NaN NaN NaN 1 NaN
2017-08-07 NaN NaN NaN NaN NaN
2017-08-14 NaN NaN NaN NaN NaN
2017-08-28 NaN NaN NaN NaN 5
And I would like to make a rolling mean for each row on the previous 3 valid values(not empty rows) and save in another df:
last_3
time_axis
2017-02-07 1 # still there is only a row
2017-02-14 1 # only a valid value(in the first row) -> average is the value itself
2017-03-20 1.5 # average on the previous rows (only 2 rows contain value-> (2+1)/2
2017-04-03 2 # average on the previous rows with non-NaN values(2017-02-14 excluded) (2+3+1)/3
2017-05-15 2 # Same reason as the previous row
2017-06-05 2 # Same reason
2017-07-10 3.6 # Now the considered values are:2,3,6
2017-07-17 4.3 # considered values: 4,6,3
2017-07-24 3.6 # considered values: 1,4,6
2017-08-07 3.6 # no new values in this row, so again 1,4,6
2017-08-14 3.6 # same reason
2017-08-28 3.3 # now the considered values are: 5,1,4
I was trying deleting the empty rows in the first dataframe and then apply rolling and mean, but I think it is the wrong approach(df1 in my example already exist):
df2 = df.dropna(how='all')
df1['last_3'] = df2.mean(axis=1).rolling(window=3, min_periods=3).mean()
I think you need:
df2 = df.dropna(how='all')
df['last_3'] = df2.mean(axis=1).rolling(window=3, min_periods=1).mean()
df['last_3'] = df['last_3'].ffill()
print (df)
a001 a002 a003 a004 a005 last_3
2017-02-07 1.0 NaN NaN NaN NaN 1.000000
2017-02-14 NaN NaN NaN NaN NaN 1.000000
2017-03-20 NaN NaN 2.0 NaN NaN 1.500000
2017-04-03 NaN 3.0 NaN NaN NaN 2.000000
2017-05-15 NaN NaN NaN NaN NaN 2.000000
2017-06-05 NaN NaN NaN NaN NaN 2.000000
2017-07-10 NaN 6.0 NaN NaN NaN 3.666667
2017-07-17 4.0 NaN NaN NaN NaN 4.333333
2017-07-24 NaN NaN NaN 1.0 NaN 3.666667
2017-08-07 NaN NaN NaN NaN NaN 3.666667
2017-08-14 NaN NaN NaN NaN NaN 3.666667
2017-08-28 NaN NaN NaN NaN 5.0 3.333333
Out[1015]: gp2
department MOBILE QA TA WEB MOBILE QA TA WEB
minutes minutes minutes minutes growth growth growth growth
period
2016-12-24 NaN NaN 140.0 400.0 NaN NaN 0.0 260.0
2016-12-25 NaN NaN NaN 80.0 NaN NaN NaN -320.0
2016-12-26 NaN NaN NaN 20.0 NaN NaN NaN -60.0
2016-12-27 NaN 45.0 NaN 180.0 NaN 25.0 NaN 135.0
2016-12-28 600.0 NaN NaN 15.0 420.0 NaN NaN -585.0
... ... ... ... ... ... ... ... ...
2017-01-03 NaN NaN NaN 80.0 NaN NaN NaN -110.0
2017-01-04 20.0 NaN NaN NaN -60.0 NaN NaN NaN
2017-02-01 120.0 NaN NaN NaN 100.0 NaN NaN NaN
2017-02-02 45.0 NaN NaN NaN -75.0 NaN NaN NaN
2017-02-03 NaN 45.0 NaN 30.0 NaN 0.0 NaN -15.0
I need MOBILE.minutes and MOBILE.growth to be one after another.
I tried this
In [1019]:gp2.columns = gp2.columns.sort_values()
In [1020]: gp2
Out[1020]:
department MOBILE QA TA WEB
growth minutes growth minutes growth minutes growth minutes
period
2016-12-24 NaN NaN 140.0 400.0 NaN NaN 0.0 260.0
2016-12-25 NaN NaN NaN 80.0 NaN NaN NaN -320.0
2016-12-26 NaN NaN NaN 20.0 NaN NaN NaN -60.0
2016-12-27 NaN 45.0 NaN 180.0 NaN 25.0 NaN 135.0
2016-12-28 600.0 NaN NaN 15.0 420.0 NaN NaN -585.0
... ... ... ... ... ... ... ... ...
2017-01-03 NaN NaN NaN 80.0 NaN NaN NaN -110.0
2017-01-04 20.0 NaN NaN NaN -60.0 NaN NaN NaN
2017-02-01 120.0 NaN NaN NaN 100.0 NaN NaN NaN
2017-02-02 45.0 NaN NaN NaN -75.0 NaN NaN NaN
2017-02-03 NaN 45.0 NaN 30.0 NaN 0.0 NaN -15.0
It sorted just the columns but didn't assign them proper values.
Just use df.sort_index:
df = df.sort_index(level=[0, 1], axis=1)
print(df)
MOBILE QA TA WEB
growth minutes growth minutes growth minutes growth minutes
period
2016-12-24 NaN NaN NaN NaN 0.0 140.0 260.0 400.0
2016-12-25 NaN NaN NaN NaN NaN NaN -320.0 80.0
2016-12-26 NaN NaN NaN NaN NaN NaN -60.0 20.0
2016-12-27 NaN NaN 25.0 45.0 NaN NaN 135.0 180.0
2016-12-28 420.0 600.0 NaN NaN NaN NaN -585.0 15.0
2017-01-03 NaN NaN NaN NaN NaN NaN -110.0 80.0
2017-01-04 -60.0 20.0 NaN NaN NaN NaN NaN NaN
2017-02-01 100.0 120.0 NaN NaN NaN NaN NaN NaN
2017-02-02 -75.0 45.0 NaN NaN NaN NaN NaN NaN
2017-02-03 NaN NaN 0.0 45.0 NaN NaN -15.0 30.0
I have the following DataFrame:
In [299]: df
Out[299]:
a b
DATE
2017-05-28 15:01:37 0.0 1.0
2017-05-28 15:01:39 1.0 0.0
2017-05-28 15:01:39 1.0 0.0
2017-05-28 15:01:39 1.0 0.0
2017-05-28 15:01:39 1.0 0.0
2017-05-28 15:01:39 1.0 0.0
2017-05-28 15:01:42 1.0 0.0
2017-05-28 15:02:10 1.0 0.0
2017-05-28 15:02:14 0.0 1.0
2017-05-28 15:02:23 0.0 1.0
2017-05-28 15:02:28 1.0 0.0
2017-05-28 15:02:34 0.0 1.0
2017-05-28 15:02:34 0.0 1.0
I can get the shape I'm looking for by doing the following:
In [300]: xa = df.groupby(df.index).apply(lambda x: x['a'].values)
In [301]: xb = df.groupby(df.index).apply(lambda x: x['b'].values)
In [302]: ya = pd.DataFrame(xa.tolist(), index=xa.index)
In [303]: yb = pd.DataFrame(xb.tolist(), index=xb.index)
In [304]: new_df = pd.concat([ya, yb], axis=1, keys=['a', 'b'])
In [305]: new_df
Out[305]:
a b
0 1 2 3 4 0 1 2 3 4
DATE
2017-05-28 15:01:37 0.0 NaN NaN NaN NaN 1.0 NaN NaN NaN NaN
2017-05-28 15:01:39 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0
2017-05-28 15:01:42 1.0 NaN NaN NaN NaN 0.0 NaN NaN NaN NaN
2017-05-28 15:02:10 1.0 NaN NaN NaN NaN 0.0 NaN NaN NaN NaN
2017-05-28 15:02:14 0.0 NaN NaN NaN NaN 1.0 NaN NaN NaN NaN
2017-05-28 15:02:23 0.0 NaN NaN NaN NaN 1.0 NaN NaN NaN NaN
2017-05-28 15:02:28 1.0 NaN NaN NaN NaN 0.0 NaN NaN NaN NaN
2017-05-28 15:02:34 0.0 0.0 NaN NaN NaN 1.0 1.0 NaN NaN NaN
Is there a more efficient way to get the same result?
Append an index level with cumcount
df.set_index(df.groupby(level='DATE').cumcount(), append=True).unstack()
a b
0 1 2 3 4 0 1 2 3 4
DATE
2017-05-28 15:01:37 0.0 NaN NaN NaN NaN 1.0 NaN NaN NaN NaN
2017-05-28 15:01:39 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0
2017-05-28 15:01:42 1.0 NaN NaN NaN NaN 0.0 NaN NaN NaN NaN
2017-05-28 15:02:10 1.0 NaN NaN NaN NaN 0.0 NaN NaN NaN NaN
2017-05-28 15:02:14 0.0 NaN NaN NaN NaN 1.0 NaN NaN NaN NaN
2017-05-28 15:02:23 0.0 NaN NaN NaN NaN 1.0 NaN NaN NaN NaN
2017-05-28 15:02:28 1.0 NaN NaN NaN NaN 0.0 NaN NaN NaN NaN
2017-05-28 15:02:34 0.0 0.0 NaN NaN NaN 1.0 1.0 NaN NaN NaN