I'm trying to create a line/area chart, which looks like a gantt chart with plotly in python. That's because i do not have a column of start and end (required for px.timeline). Instead, i have several vectors which begins in a certain place in time and decrease over several months. To better illustrate, thats my dataframe:
periods 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
start
2018-12 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2019-01 252.0 240.0 228.0 208.0 199.0 182.0 168.0 152.0 141.0 132.0 120.0 108.0 91.0 77.0 66.0 52.0 37.0 19.0 7.0
2019-02 140.0 135.0 129.0 123.0 114.0 101.0 99.0 91.0 84.0 74.0 62.0 49.0 45.0 39.0 33.0 26.0 20.0 10.0 3.0
2019-03 97.0 93.0 85.0 79.0 73.0 68.0 62.0 60.0 54.0 50.0 45.0 41.0 37.0 31.0 23.0 18.0 11.0 4.0 NaN
2019-04 92.0 90.0 86.0 82.0 78.0 73.0 67.0 58.0 51.0 46.0 41.0 38.0 36.0 34.0 32.0 19.0 14.0 3.0 1.0
2019-05 110.0 106.0 98.0 94.0 88.0 84.0 81.0 74.0 66.0 64.0 61.0 53.0 42.0 37.0 32.0 20.0 15.0 11.0 1.0
2019-06 105.0 101.0 96.0 87.0 84.0 80.0 75.0 69.0 65.0 60.0 56.0 46.0 40.0 32.0 30.0 18.0 10.0 6.0 2.0
2019-07 123.0 121.0 113.0 105.0 97.0 90.0 82.0 77.0 74.0 69.0 68.0 66.0 55.0 47.0 36.0 32.0 24.0 11.0 2.0
2019-08 127.0 122.0 117.0 112.0 108.0 100.0 94.0 82.0 78.0 69.0 65.0 58.0 53.0 43.0 35.0 24.0 17.0 8.0 2.0
2019-09 122.0 114.0 106.0 100.0 90.0 83.0 76.0 69.0 58.0 50.0 45.0 39.0 32.0 28.0 24.0 17.0 8.0 5.0 1.0
2019-10 164.0 161.0 151.0 138.0 129.0 121.0 114.0 102.0 95.0 88.0 81.0 72.0 62.0 56.0 48.0 40.0 22.0 16.0 5.0
2019-11 216.0 214.0 202.0 193.0 181.0 165.0 150.0 139.0 126.0 116.0 107.0 95.0 82.0 65.0 54.0 44.0 31.0 14.0 7.0
2019-12 341.0 327.0 311.0 294.0 274.0 261.0 245.0 225.0 210.0 191.0 171.0 136.0 117.0 96.0 79.0 55.0 45.0 26.0 6.0
2020-01 1167.0 1139.0 1089.0 1009.0 948.0 881.0 826.0 745.0 682.0 608.0 539.0 473.0 401.0 346.0 292.0 244.0 171.0 90.0 31.0
2020-02 280.0 274.0 262.0 247.0 239.0 226.0 204.0 184.0 169.0 158.0 141.0 125.0 105.0 89.0 68.0 55.0 29.0 18.0 3.0
2020-03 723.0 713.0 668.0 629.0 581.0 537.0 499.0 462.0 419.0 384.0 340.0 293.0 268.0 215.0 172.0 136.0 103.0 67.0 19.0
2020-04 1544.0 1502.0 1420.0 1337.0 1256.0 1149.0 1065.0 973.0 892.0 795.0 715.0 637.0 538.0 463.0 371.0 283.0 199.0 111.0 29.0
2020-05 1355.0 1313.0 1241.0 1175.0 1102.0 1046.0 970.0 890.0 805.0 726.0 652.0 569.0 488.0 415.0 331.0 255.0 180.0 99.0 19.0
2020-06 1042.0 1009.0 949.0 886.0 834.0 784.0 740.0 670.0 611.0 558.0 493.0 438.0 380.0 312.0 257.0 195.0 125.0 78.0 NaN
2020-07 719.0 698.0 663.0 624.0 595.0 547.0 512.0 460.0 424.0 387.0 341.0 301.0 256.0 215.0 172.0 124.0 90.0 NaN NaN
2020-08 655.0 633.0 605.0 566.0 537.0 492.0 453.0 417.0 377.0 333.0 294.0 259.0 222.0 189.0 162.0 118.0 NaN NaN NaN
2020-09 715.0 687.0 647.0 617.0 562.0 521.0 479.0 445.0 408.0 371.0 331.0 297.0 257.0 208.0 165.0 NaN NaN NaN NaN
2020-10 345.0 333.0 313.0 297.0 284.0 267.0 252.0 225.0 201.0 183.0 159.0 141.0 123.0 108.0 NaN NaN NaN NaN NaN
2020-11 1254.0 1221.0 1162.0 1094.0 1027.0 965.0 892.0 816.0 743.0 682.0 607.0 549.0 464.0 NaN NaN NaN NaN NaN NaN
2020-12 387.0 379.0 352.0 338.0 319.0 292.0 275.0 257.0 230.0 207.0 185.0 157.0 NaN NaN NaN NaN NaN NaN NaN
2021-01 805.0 782.0 742.0 692.0 649.0 599.0 551.0 500.0 463.0 417.0 371.0 NaN NaN NaN NaN NaN NaN NaN NaN
2021-02 469.0 458.0 434.0 407.0 380.0 357.0 336.0 317.0 296.0 263.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-03 1540.0 1491.0 1390.0 1302.0 1221.0 1128.0 1049.0 967.0 864.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-04 1265.0 1221.0 1145.0 1086.0 1006.0 937.0 862.0 793.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-05 558.0 548.0 520.0 481.0 446.0 417.0 389.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-06 607.0 589.0 560.0 517.0 484.0 455.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-07 597.0 572.0 543.0 511.0 477.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-08 923.0 902.0 850.0 792.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-09 975.0 952.0 899.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-10 647.0 628.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-11 131.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
As you can see, for each period, i have a start at 0, until the last period available. Right now, my code is this:
vectors = []
for i in pivot_period.index:
vectors.append(list(pivot_period.loc[i]))
fig = px.area(y=[i for i in vectors])
If you plot the graph, you will see that the x-axis is the number of periods. However, when i try to implement the dates (which are the index), it returns a mislength, as long as i have 18 periods vs 36 dates. My idea, is to plot something like this (sorry for the terrible pic):
In a way that could visualize a decay of each vector in its own timeline. Any ideas?
generating an area figure from this data is simple: px.area(df, x=df.index, y=df.columns)
I do not see where the jobs/tasks come from in this dataset to match the image attached
df = pd.read_csv(io.StringIO("""periods 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
start
2018-12 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2019-01 252.0 240.0 228.0 208.0 199.0 182.0 168.0 152.0 141.0 132.0 120.0 108.0 91.0 77.0 66.0 52.0 37.0 19.0 7.0
2019-02 140.0 135.0 129.0 123.0 114.0 101.0 99.0 91.0 84.0 74.0 62.0 49.0 45.0 39.0 33.0 26.0 20.0 10.0 3.0
2019-03 97.0 93.0 85.0 79.0 73.0 68.0 62.0 60.0 54.0 50.0 45.0 41.0 37.0 31.0 23.0 18.0 11.0 4.0 NaN
2019-04 92.0 90.0 86.0 82.0 78.0 73.0 67.0 58.0 51.0 46.0 41.0 38.0 36.0 34.0 32.0 19.0 14.0 3.0 1.0
2019-05 110.0 106.0 98.0 94.0 88.0 84.0 81.0 74.0 66.0 64.0 61.0 53.0 42.0 37.0 32.0 20.0 15.0 11.0 1.0
2019-06 105.0 101.0 96.0 87.0 84.0 80.0 75.0 69.0 65.0 60.0 56.0 46.0 40.0 32.0 30.0 18.0 10.0 6.0 2.0
2019-07 123.0 121.0 113.0 105.0 97.0 90.0 82.0 77.0 74.0 69.0 68.0 66.0 55.0 47.0 36.0 32.0 24.0 11.0 2.0
2019-08 127.0 122.0 117.0 112.0 108.0 100.0 94.0 82.0 78.0 69.0 65.0 58.0 53.0 43.0 35.0 24.0 17.0 8.0 2.0
2019-09 122.0 114.0 106.0 100.0 90.0 83.0 76.0 69.0 58.0 50.0 45.0 39.0 32.0 28.0 24.0 17.0 8.0 5.0 1.0
2019-10 164.0 161.0 151.0 138.0 129.0 121.0 114.0 102.0 95.0 88.0 81.0 72.0 62.0 56.0 48.0 40.0 22.0 16.0 5.0
2019-11 216.0 214.0 202.0 193.0 181.0 165.0 150.0 139.0 126.0 116.0 107.0 95.0 82.0 65.0 54.0 44.0 31.0 14.0 7.0
2019-12 341.0 327.0 311.0 294.0 274.0 261.0 245.0 225.0 210.0 191.0 171.0 136.0 117.0 96.0 79.0 55.0 45.0 26.0 6.0
2020-01 1167.0 1139.0 1089.0 1009.0 948.0 881.0 826.0 745.0 682.0 608.0 539.0 473.0 401.0 346.0 292.0 244.0 171.0 90.0 31.0
2020-02 280.0 274.0 262.0 247.0 239.0 226.0 204.0 184.0 169.0 158.0 141.0 125.0 105.0 89.0 68.0 55.0 29.0 18.0 3.0
2020-03 723.0 713.0 668.0 629.0 581.0 537.0 499.0 462.0 419.0 384.0 340.0 293.0 268.0 215.0 172.0 136.0 103.0 67.0 19.0
2020-04 1544.0 1502.0 1420.0 1337.0 1256.0 1149.0 1065.0 973.0 892.0 795.0 715.0 637.0 538.0 463.0 371.0 283.0 199.0 111.0 29.0
2020-05 1355.0 1313.0 1241.0 1175.0 1102.0 1046.0 970.0 890.0 805.0 726.0 652.0 569.0 488.0 415.0 331.0 255.0 180.0 99.0 19.0
2020-06 1042.0 1009.0 949.0 886.0 834.0 784.0 740.0 670.0 611.0 558.0 493.0 438.0 380.0 312.0 257.0 195.0 125.0 78.0 NaN
2020-07 719.0 698.0 663.0 624.0 595.0 547.0 512.0 460.0 424.0 387.0 341.0 301.0 256.0 215.0 172.0 124.0 90.0 NaN NaN
2020-08 655.0 633.0 605.0 566.0 537.0 492.0 453.0 417.0 377.0 333.0 294.0 259.0 222.0 189.0 162.0 118.0 NaN NaN NaN
2020-09 715.0 687.0 647.0 617.0 562.0 521.0 479.0 445.0 408.0 371.0 331.0 297.0 257.0 208.0 165.0 NaN NaN NaN NaN
2020-10 345.0 333.0 313.0 297.0 284.0 267.0 252.0 225.0 201.0 183.0 159.0 141.0 123.0 108.0 NaN NaN NaN NaN NaN
2020-11 1254.0 1221.0 1162.0 1094.0 1027.0 965.0 892.0 816.0 743.0 682.0 607.0 549.0 464.0 NaN NaN NaN NaN NaN NaN
2020-12 387.0 379.0 352.0 338.0 319.0 292.0 275.0 257.0 230.0 207.0 185.0 157.0 NaN NaN NaN NaN NaN NaN NaN
2021-01 805.0 782.0 742.0 692.0 649.0 599.0 551.0 500.0 463.0 417.0 371.0 NaN NaN NaN NaN NaN NaN NaN NaN
2021-02 469.0 458.0 434.0 407.0 380.0 357.0 336.0 317.0 296.0 263.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-03 1540.0 1491.0 1390.0 1302.0 1221.0 1128.0 1049.0 967.0 864.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-04 1265.0 1221.0 1145.0 1086.0 1006.0 937.0 862.0 793.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-05 558.0 548.0 520.0 481.0 446.0 417.0 389.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-06 607.0 589.0 560.0 517.0 484.0 455.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-07 597.0 572.0 543.0 511.0 477.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-08 923.0 902.0 850.0 792.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-09 975.0 952.0 899.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-10 647.0 628.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2021-11 131.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN""")
,sep="\s+").drop(0).set_index("periods")
px.area(df, x=df.index, y=df.columns)
Related
Let's say I have a panel dataframe with lots of NaNs inside as follow:
import pandas as pd
import numpy as np
np.random.seed(2021)
dates = pd.date_range('20130226', periods=720)
df = pd.DataFrame(np.random.randint(0, 100, size=(720, 3)), index=dates, columns=list('ABC'))
for col in df.columns:
df.loc[df.sample(frac=0.4).index, col] = pd.np.nan
df
Out:
A B C
2013-02-26 NaN NaN NaN
2013-02-27 NaN NaN 44.0
2013-02-28 62.0 NaN 29.0
2013-03-01 21.0 NaN 24.0
2013-03-02 12.0 70.0 70.0
... ... ...
2015-02-11 38.0 42.0 NaN
2015-02-12 67.0 NaN NaN
2015-02-13 27.0 10.0 74.0
2015-02-14 18.0 NaN NaN
2015-02-15 NaN NaN NaN
I need to apply df.fillna(method='bfill') or df.fillna(method='ffill') to the dataframe only if they are in same year and month:
For example, if I apply df.fillna(method='bfill'), the expected result will like this:
A B C
2013-02-26 62.0 NaN 44.0
2013-02-27 62.0 NaN 44.0
2013-02-28 62.0 NaN 29.0
2013-03-01 21.0 70.0 24.0
2013-03-02 12.0 70.0 70.0
... ... ...
2015-02-11 38.0 42.0 74.0
2015-02-12 67.0 10.0 74.0
2015-02-13 27.0 10.0 74.0
2015-02-14 18.0 NaN NaN
2015-02-15 NaN NaN NaN
How could I do that in Pandas? Thanks.
You could resample by M (month) and transform bfill:
>>> df.resample("M").transform('bfill')
A B C
2013-02-26 62.0 NaN 44.0
2013-02-27 62.0 NaN 44.0
2013-02-28 62.0 NaN 29.0
2013-03-01 21.0 70.0 24.0
2013-03-02 12.0 70.0 70.0
... ... ... ...
2015-02-11 38.0 42.0 74.0
2015-02-12 67.0 10.0 74.0
2015-02-13 27.0 10.0 74.0
2015-02-14 18.0 NaN NaN
2015-02-15 NaN NaN NaN
[720 rows x 3 columns]
>>>
For specific columns:
>>> df[['A', 'B']] = df.resample("M")[['A', 'B']].transform('bfill')
>>> df
A B C
2013-02-26 62.0 NaN NaN
2013-02-27 62.0 NaN 44.0
2013-02-28 62.0 NaN 29.0
2013-03-01 21.0 70.0 24.0
2013-03-02 12.0 70.0 70.0
... ... ... ...
2015-02-11 38.0 42.0 NaN
2015-02-12 67.0 10.0 NaN
2015-02-13 27.0 10.0 74.0
2015-02-14 18.0 NaN NaN
2015-02-15 NaN NaN NaN
[720 rows x 3 columns]
>>>
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)
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.
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.
I have a dataframe that has one column and a timestamp index including anywhere from 2 to 7 days:
kWh
Timestamp
2017-07-08 06:00:00 0.00
2017-07-08 07:00:00 752.75
2017-07-08 08:00:00 1390.20
2017-07-08 09:00:00 2027.65
2017-07-08 10:00:00 2447.27
.... ....
2017-07-12 20:00:00 167.64
2017-07-12 21:00:00 0.00
2017-07-12 22:00:00 0.00
2017-07-12 23:00:00 0.00
I would like to transpose the kWh column so that one day's worth of values (hourly granularity, so 24 values/day) fill up a row. And the next row is the next day of values and so on (so five days of forecasted data has five rows with 24 elements each).
Because my query of the data comes in the vertical format, and my regression and subsequent analysis already occurs in the vertical format, I don't want to change the process too much and am hoping there is a simpler way. I have tried giving a multi-index with df.index.hour and then using unstack(), but I get a huge dataframe with NaN values everywhere.
Is there an elegant way to do this?
If we start from a frame like
In [25]: df = pd.DataFrame({"kWh": [1]}, index=pd.date_range("2017-07-08",
"2017-07-12", freq="1H").rename("Timestamp")).cumsum()
In [26]: df.head()
Out[26]:
kWh
Timestamp
2017-07-08 00:00:00 1
2017-07-08 01:00:00 2
2017-07-08 02:00:00 3
2017-07-08 03:00:00 4
2017-07-08 04:00:00 5
we can make date and hour columns and then pivot:
In [27]: df["date"] = df.index.date
In [28]: df["hour"] = df.index.hour
In [29]: df.pivot(index="date", columns="hour", values="kWh")
Out[29]:
hour 0 1 2 3 4 5 6 7 8 9 ... \
date ...
2017-07-08 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 ...
2017-07-09 25.0 26.0 27.0 28.0 29.0 30.0 31.0 32.0 33.0 34.0 ...
2017-07-10 49.0 50.0 51.0 52.0 53.0 54.0 55.0 56.0 57.0 58.0 ...
2017-07-11 73.0 74.0 75.0 76.0 77.0 78.0 79.0 80.0 81.0 82.0 ...
2017-07-12 97.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN ...
hour 14 15 16 17 18 19 20 21 22 23
date
2017-07-08 15.0 16.0 17.0 18.0 19.0 20.0 21.0 22.0 23.0 24.0
2017-07-09 39.0 40.0 41.0 42.0 43.0 44.0 45.0 46.0 47.0 48.0
2017-07-10 63.0 64.0 65.0 66.0 67.0 68.0 69.0 70.0 71.0 72.0
2017-07-11 87.0 88.0 89.0 90.0 91.0 92.0 93.0 94.0 95.0 96.0
2017-07-12 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
[5 rows x 24 columns]
Not sure why your MultiIndex code doesn't work.
I'm assuming your MultiIndex code is something along the lines, which gives the same output as the pivot:
In []
df = pd.DataFrame({"kWh": [1]}, index=pd.date_range("2017-07-08",
"2017-07-12", freq="1H").rename("Timestamp")).cumsum()
df.index = pd.MultiIndex.from_arrays([df.index.date, df.index.hour], names=['Date','Hour'])
df.unstack()
Out[]:
kWh ... \
Hour 0 1 2 3 4 5 6 7 8 9 ...
Date ...
2017-07-08 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 ...
2017-07-09 25.0 26.0 27.0 28.0 29.0 30.0 31.0 32.0 33.0 34.0 ...
2017-07-10 49.0 50.0 51.0 52.0 53.0 54.0 55.0 56.0 57.0 58.0 ...
2017-07-11 73.0 74.0 75.0 76.0 77.0 78.0 79.0 80.0 81.0 82.0 ...
2017-07-12 97.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN ...
Hour 14 15 16 17 18 19 20 21 22 23
Date
2017-07-08 15.0 16.0 17.0 18.0 19.0 20.0 21.0 22.0 23.0 24.0
2017-07-09 39.0 40.0 41.0 42.0 43.0 44.0 45.0 46.0 47.0 48.0
2017-07-10 63.0 64.0 65.0 66.0 67.0 68.0 69.0 70.0 71.0 72.0
2017-07-11 87.0 88.0 89.0 90.0 91.0 92.0 93.0 94.0 95.0 96.0
2017-07-12 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
[5 rows x 24 columns]