Converting row in timeseries data to column - python

Suppose that I have a timeseries like
In [41]: df = pd.DataFrame(dict(names=list('abcaabcabbcc'), vals=np.random.randint(0, 10, 12)), index
...: =pd.date_range('2017-03-01', periods=12))
In [42]: df
Out[42]:
names vals
2017-03-01 a 2
2017-03-02 b 9
2017-03-03 c 6
2017-03-04 a 6
2017-03-05 a 5
2017-03-06 b 2
2017-03-07 c 3
2017-03-08 a 1
2017-03-09 b 1
2017-03-10 b 1
2017-03-11 c 1
2017-03-12 c 0
How can I convert the names row into the column headers, under which the corresponding vals are? e.g.
a b c
2017-03-01 2 nan nan
2017-03-02 nan 9 nan
...
I have been playing around with pd.melt as well as trying to add the names to the index and then reset the index so that they become columns somehow, but I am very stuck.

You can use:
print (pd.pivot(index=df.index, columns=df['names'], values=df['vals']))
Or:
print (df.set_index('names', append=True)['vals'].unstack())
names a b c
2017-03-01 4.0 NaN NaN
2017-03-02 NaN 0.0 NaN
2017-03-03 NaN NaN 3.0
2017-03-04 8.0 NaN NaN
2017-03-05 0.0 NaN NaN
2017-03-06 NaN 0.0 NaN
2017-03-07 NaN NaN 9.0
2017-03-08 6.0 NaN NaN
2017-03-09 NaN 6.0 NaN
2017-03-10 NaN 0.0 NaN
2017-03-11 NaN NaN 3.0
2017-03-12 NaN NaN 9.0
print (df.reset_index().pivot_table(index='index', columns='names', values='vals'))

you can also use unstack():
In [12]: df.set_index('names', append=True).unstack('names')
Out[12]:
vals
names a b c
2017-03-01 1.0 NaN NaN
2017-03-02 NaN 4.0 NaN
2017-03-03 NaN NaN 5.0
2017-03-04 8.0 NaN NaN
2017-03-05 8.0 NaN NaN
2017-03-06 NaN 5.0 NaN
2017-03-07 NaN NaN 7.0
2017-03-08 5.0 NaN NaN
2017-03-09 NaN 7.0 NaN
2017-03-10 NaN 4.0 NaN
2017-03-11 NaN NaN 3.0
2017-03-12 NaN NaN 4.0

Related

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
... ...

Convert two pandas rows into one

I want to convert below dataframe,
ID TYPE A B
0 1 MISSING 0.0 0.0
1 2 1T 1.0 2.0
2 2 2T 3.0 4.0
3 3 MISSING 0.0 0.0
4 4 2T 10.0 4.0
5 5 CBN 15.0 20.0
6 5 DSV 25.0 35.0
to:
ID MISSING_A MISSING_B 1T_A 1T_B 2T_A 2T_B CBN_A CBN_B DSV_A DSV_B
0 1 0.0 0.0 NaN NaN NaN NaN NaN NaN NaN NaN
1 2 NaN NaN 1.0 2.0 3.0 4.0 NaN NaN NaN NaN
3 3 0.0 0.0 NaN NaN NaN NaN NaN NaN NaN NaN
4 4 10.0 4.0 NaN NaN 10.0 4.0 NaN NaN NaN NaN
5 5 NaN NaN NaN NaN NaN NaN 15.0 20.0 25.0 35.0
For IDs with multiple types, multiple rows for A and B to merge into one row as shown above.
You are looking for a pivot, which will end up giving you a multi-index. You'll need to join those columns to get the suffix you are looking for.
df = df.pivot(index='ID',columns='TYPE', values=['A','B'])
df.columns = ['_'.join(reversed(col)).strip() for col in df.columns.values]
df.reset_index()

ReArrange Pandas DataFrame date columns in date order

I have a pandas dataframe that summarises sales by calendar month & outputs something like:
Month level_0 UNIQUE_ID 102018 112018 12018 122017 122018 22018 32018 42018 52018 62018 72018 82018 92018
0 SOLD_QUANTITY 01 3692.0 5182.0 3223.0 1292.0 2466.0 2396.0 2242.0 2217.0 3590.0 2593.0 1665.0 3371.0 3069.0
1 SOLD_QUANTITY 011 3.0 6.0 NaN NaN 7.0 5.0 2.0 1.0 5.0 NaN 1.0 1.0 3.0
2 SOLD_QUANTITY 02 370.0 130.0 NaN NaN 200.0 NaN NaN 269.0 202.0 NaN 201.0 125.0 360.0
3 SOLD_QUANTITY 03 2.0 6.0 NaN NaN 2.0 1.0 NaN 6.0 11.0 9.0 2.0 3.0 5.0
4 SOLD_QUANTITY 08 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 175.0 NaN NaN
I want to be able to programmatically re-arrange the column headers in ascending date order (eg starting 122017, 12018, 22018...). I need to do it in a way that is programmatic as every way the report runs, it will be a different list of months as it runs every month for last 365 days.
The index data type:
Index(['level_0', 'UNIQUE_ID', '102018', '112018', '12018', '122017', '122018',
'22018', '32018', '42018', '52018', '62018', '72018', '82018', '92018'],
dtype='object', name='Month')
Use set_index for only dates columns, convert them to datetimes and get order positions by argsort, then change ordering with iloc:
df = df.set_index(['level_0','UNIQUE_ID'])
df = df.iloc[:, pd.to_datetime(df.columns, format='%m%Y').argsort()].reset_index()
print (df)
level_0 UNIQUE_ID 122017 12018 22018 32018 42018 52018 \
0 SOLD_QUANTITY 1 1292.0 3223.0 2396.0 2242.0 2217.0 3590.0
1 SOLD_QUANTITY 11 NaN NaN 5.0 2.0 1.0 5.0
2 SOLD_QUANTITY 2 NaN NaN NaN NaN 269.0 202.0
3 SOLD_QUANTITY 3 NaN NaN 1.0 NaN 6.0 11.0
4 SOLD_QUANTITY 8 NaN NaN NaN NaN NaN NaN
62018 72018 82018 92018 102018 112018 122018
0 2593.0 1665.0 3371.0 3069.0 3692.0 5182.0 2466.0
1 NaN 1.0 1.0 3.0 3.0 6.0 7.0
2 NaN 201.0 125.0 360.0 370.0 130.0 200.0
3 9.0 2.0 3.0 5.0 2.0 6.0 2.0
4 NaN 175.0 NaN NaN NaN NaN NaN
Another idea is create month period index by DatetimeIndex.to_period, so is possible use sort_index:
df = df.set_index(['level_0','UNIQUE_ID'])
df.columns = pd.to_datetime(df.columns, format='%m%Y').to_period('m')
#alternative for convert to datetimes
#df.columns = pd.to_datetime(df.columns, format='%m%Y')
df = df.sort_index(axis=1).reset_index()
print (df)
level_0 UNIQUE_ID 2017-12 2018-01 2018-02 2018-03 2018-04 \
0 SOLD_QUANTITY 1 1292.0 3223.0 2396.0 2242.0 2217.0
1 SOLD_QUANTITY 11 NaN NaN 5.0 2.0 1.0
2 SOLD_QUANTITY 2 NaN NaN NaN NaN 269.0
3 SOLD_QUANTITY 3 NaN NaN 1.0 NaN 6.0
4 SOLD_QUANTITY 8 NaN NaN NaN NaN NaN
2018-05 2018-06 2018-07 2018-08 2018-09 2018-10 2018-11 2018-12
0 3590.0 2593.0 1665.0 3371.0 3069.0 3692.0 5182.0 2466.0
1 5.0 NaN 1.0 1.0 3.0 3.0 6.0 7.0
2 202.0 NaN 201.0 125.0 360.0 370.0 130.0 200.0
3 11.0 9.0 2.0 3.0 5.0 2.0 6.0 2.0
4 NaN NaN 175.0 NaN NaN NaN NaN NaN

Pandas: datetime indexed series to time indexed date columns dataframe

I have a datetime indexed series like this:
2018-08-27 17:45:01 1
2018-08-27 16:01:12 1
2018-08-27 13:48:47 1
2018-08-26 22:26:40 2
2018-08-26 20:10:42 1
2018-08-26 18:20:32 1
2018-08-25 23:07:51 1
2018-08-25 01:46:08 1
2018-09-18 14:08:23 1
2018-09-17 19:38:38 1
2018-09-15 22:40:45 1
What is an elegant way to reformat this into a time indexed dataframe whose columns are dates? For example:
2018-10-24 2018-06-28 2018-10-23
15:16:41 1.0 NaN NaN
15:18:16 1.0 NaN NaN
15:21:42 1.0 NaN NaN
23:35:00 NaN NaN 1.0
23:53:13 NaN 1.0 NaN
Current approach:
time_date_dict = defaultdict(partial(defaultdict, int))
for i in series.iteritems():
datetime = i[0]
value = i[1]
time_date_dict[datetime.time()][datetime.date()] = value
time_date_df = pd.DataFrame.from_dict(time_date_dict, orient='index')
Use pivot:
df1 = pd.pivot(s.index.time, s.index.date, s)
#if want strings index and columns names
#df1 = pd.pivot(s.index.strftime('%H:%M:%S'), s.index.strftime('%Y-%m-%d'), s)
print (df1)
date 2018-08-25 2018-08-26 2018-08-27 2018-09-15 2018-09-17 \
date
01:46:08 1.0 NaN NaN NaN NaN
13:48:47 NaN NaN 1.0 NaN NaN
14:08:23 NaN NaN NaN NaN NaN
16:01:12 NaN NaN 1.0 NaN NaN
17:45:01 NaN NaN 1.0 NaN NaN
18:20:32 NaN 1.0 NaN NaN NaN
19:38:38 NaN NaN NaN NaN 1.0
20:10:42 NaN 1.0 NaN NaN NaN
22:26:40 NaN 2.0 NaN NaN NaN
22:40:45 NaN NaN NaN 1.0 NaN
23:07:51 1.0 NaN NaN NaN NaN
date 2018-09-18
date
01:46:08 NaN
13:48:47 NaN
14:08:23 1.0
16:01:12 NaN
17:45:01 NaN
18:20:32 NaN
19:38:38 NaN
20:10:42 NaN
22:26:40 NaN
22:40:45 NaN
23:07:51 NaN

how to assign values to a new data frame from another data frame in python

I set up a new data frame SimMean:
columns = ['Tenor','5x16', '7x8', '2x16H']
index = range(0,12)
SimMean = pd.DataFrame(index=index, columns=columns)
SimMean
Tenor 5x16 7x8 2x16H
0 NaN NaN NaN NaN
1 NaN NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
4 NaN NaN NaN NaN
5 NaN NaN NaN NaN
6 NaN NaN NaN NaN
7 NaN NaN NaN NaN
8 NaN NaN NaN NaN
9 NaN NaN NaN NaN
10 NaN NaN NaN NaN
11 NaN NaN NaN NaN
I have another data frame FwdDf:
FwdDf
Tenor 5x16 7x8 2x16H
0 2017-01-01 50.94 34.36 43.64
1 2017-02-01 50.90 32.60 42.68
2 2017-03-01 42.66 26.26 37.26
3 2017-04-01 37.08 22.65 32.46
4 2017-05-01 42.21 20.94 33.28
5 2017-06-01 39.30 22.05 32.29
6 2017-07-01 50.90 21.80 38.51
7 2017-08-01 42.77 23.64 35.07
8 2017-09-01 37.45 19.61 32.68
9 2017-10-01 37.55 21.75 32.10
10 2017-11-01 35.61 22.73 32.90
11 2017-12-01 40.16 29.79 37.49
12 2018-01-01 53.45 36.09 47.61
13 2018-02-01 52.89 35.74 45.00
14 2018-03-01 44.67 27.79 38.62
15 2018-04-01 38.48 24.21 34.43
16 2018-05-01 43.87 22.17 34.69
17 2018-06-01 40.24 22.85 34.31
18 2018-07-01 49.98 23.58 39.96
19 2018-08-01 45.57 24.76 37.23
20 2018-09-01 38.90 21.74 34.22
21 2018-10-01 39.75 23.36 35.20
22 2018-11-01 38.04 24.20 34.62
23 2018-12-01 42.68 31.03 40.00
now I need to assign the 'Tenor' data from row 12 to row 23 in FwdDf to the new data frame SimMean.
I used
SimMean.loc[0:11,'Tenor'] = FwdDf.loc [12:23,'Tenor']
but it didn't work:
SimMean
Tenor 5x16 7x8 2x16H
0 None NaN NaN NaN
1 None NaN NaN NaN
2 None NaN NaN NaN
3 None NaN NaN NaN
4 None NaN NaN NaN
5 None NaN NaN NaN
6 None NaN NaN NaN
7 None NaN NaN NaN
8 None NaN NaN NaN
9 None NaN NaN NaN
10 None NaN NaN NaN
11 None NaN NaN NaN
I'm new to python. I would appreciate your help. Thanks
call .values so there are no index alignment issues:
In [35]:
SimMean.loc[0:11,'Tenor'] = FwdDf.loc[12:23,'Tenor'].values
SimMean
Out[35]:
Tenor 5x16 7x8 2x16H
0 2018-01-01 NaN NaN NaN
1 2018-02-01 NaN NaN NaN
2 2018-03-01 NaN NaN NaN
3 2018-04-01 NaN NaN NaN
4 2018-05-01 NaN NaN NaN
5 2018-06-01 NaN NaN NaN
6 2018-07-01 NaN NaN NaN
7 2018-08-01 NaN NaN NaN
8 2018-09-01 NaN NaN NaN
9 2018-10-01 NaN NaN NaN
10 2018-11-01 NaN NaN NaN
11 2018-12-01 NaN NaN NaN
EDIT
As your column is actually datetime then you need to convert the type again:
In [46]:
SimMean['Tenor'] = pd.to_datetime(SimMean['Tenor'])
SimMean
Out[46]:
Tenor 5x16 7x8 2x16H
0 2018-01-01 NaN NaN NaN
1 2018-02-01 NaN NaN NaN
2 2018-03-01 NaN NaN NaN
3 2018-04-01 NaN NaN NaN
4 2018-05-01 NaN NaN NaN
5 2018-06-01 NaN NaN NaN
6 2018-07-01 NaN NaN NaN
7 2018-08-01 NaN NaN NaN
8 2018-09-01 NaN NaN NaN
9 2018-10-01 NaN NaN NaN
10 2018-11-01 NaN NaN NaN
11 2018-12-01 NaN NaN NaN

Categories

Resources