Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Renaming months from number to name in pandas

i have the following dataframe:

High    Low Open    Close   Volume  Adj Close   year    pct_day
month   day                             
1   1   NaN NaN NaN NaN NaN NaN 2010.0  0.000000
2   7869.853149 7718.482498 7779.655014 7818.089966 7.471689e+07    7818.089966 2010.0  0.007826
3   7839.965652 7719.758224 7775.396255 7777.940002 8.185879e+07    7777.940002 2010.0  0.002582
4   7747.175260 7624.540007 7691.152083 7686.288672 1.018877e+08    7686.288672 2010.0  -0.000744
5   7348.487095 7236.742135 7317.313616 7287.688546 1.035424e+08    7287.688546 2010.0  -0.002499
... ... ... ... ... ... ... ... ... ...
12  27  7849.846680 7760.222526 7810.902051 7798.639258 4.678145e+07    7798.639258 2009.5  -0.000833
28  7746.209996 7678.152204 7713.497907 7710.449358 4.187133e+07    7710.449358 2009.5  0.000578
29  7357.001540 7291.827806 7319.393874 7338.938345 4.554891e+07    7338.938345 2009.5  0.003321
30  7343.726938 7276.871507 7322.123779 7302.545316 3.967812e+07    7302.545316 2009.5  -0.000312
31  NaN NaN NaN NaN NaN NaN 2009.5  0.000000

Since it is not clear from the above pasted dataframe, below is a snapshot:

enter image description here

The months are in 1,2 3 ... Is it possible to rename the month index to Jan Feb Mar format?

Edit :

I am having a hard time implementing the example by @ChihebNexus

My code is as follows since it is a datetime :

full_dates = pd.date_range(start, end)
data = data.reindex(full_dates)
data['year'] = data.index.year
data['month'] = data.index.month
data['week'] = data.index.week
data['day'] = data.index.day
data.set_index('month',append=True,inplace=True)
data.set_index('week',append=True,inplace=True)
data.set_index('day',append=True,inplace=True)
df = data.groupby(['month', 'day']).mean()
like image 845
Slartibartfast Avatar asked May 16 '20 19:05

Slartibartfast


People also ask

How do I sort the month name in pandas?

Sort values by month using sort_values() and creating a month dictionary. So you can see the result is a sorted dataframe rows by month name.

How use pandas rename function?

You can use the rename() method of pandas. DataFrame to change column/index name individually. Specify the original name and the new name in dict like {original name: new name} to columns / index parameter of rename() . columns is for the column name, and index is for the index name.


2 Answers

I would do it using calendar and pd.CategoricalDtype to ensure sorting works correctly.

import pandas as pd
import numpy as np
import calendar

#Create dummy dataframe
dateindx = pd.date_range('2019-01-01', '2019-12-31', freq='D')

df = pd.DataFrame(np.random.randint(0,1000, (len(dateindx), 5)), 
             index=pd.MultiIndex.from_arrays([dateindx.month, dateindx.day]),
             columns=['High', 'Low','Open', 'Close','Volume'])

#Use calendar library for abbreviations and order
dd=dict((enumerate(calendar.month_abbr)))

#rename level zero of multiindex
df = df.rename(index=dd,level=0)

#Create calendar month data type with order for sorting
cal_dtype = pd.CategoricalDtype(list(calendar.month_abbr), ordered=True)

#Change the dtype of the level zero index
df.index = df1.index.set_levels(df.index.levels[0].astype(cal_dtype), level=0)
df

Output:

        High  Low  Open  Close  Volume
Jan 1    501  720   671    943     586
    2    410   67   207    945     284
    3    473  481   527    415     852
    4    157  809   484    592     894
    5    294   38   458     62     945
...      ...  ...   ...    ...     ...
Dec 27   305  354   347      0     726
    28   764  987   564    260      72
    29   730  151   846    137     118
    30   999  399   634    674      81
    31   347  980   441    600     676

[365 rows x 5 columns]
like image 119
Scott Boston Avatar answered Oct 18 '22 22:10

Scott Boston


For example, if we could have this DataFrame, we could use datetime package within this datetime format table like this example:

import pandas as pd
from datetime import datetime

df = pd.DataFrame(range(1, 13), columns=['month']) 
df['month'] = df.apply(
    lambda row: '{:%b}'.format(datetime.strptime(str(row['month']), '%m')),
    axis=1
) 
print(df)

Output:

0    Jan
1    Feb
2    Mar
3    Apr
4    May
5    Jun
6    Jul
7    Aug
8    Sep
9    Oct
10   Nov
11   Dec

Update: As @Ch3steR suggested. You're using a MultiIndex DataFrame. So, here is an example how you can modify it's first level index:

import pandas as pd
import numpy as np
from datetime import datetime

tuples = [(1, 10), (1, 12), (1, 13), (2, 1), (2, 20), (2, 10)]
index  = pd.MultiIndex.from_tuples(tuples, names=['month', 'day'])
serie = pd.Series(np.random.randn(len(tuples)), index=index)
df = pd.DataFrame(serie, columns=['data']) 

print(df)

               data
month day          
1     10  -0.463804
      12   1.979072
      13   0.087430
2     1    0.928077
      20  -0.697795
      10  -0.275762

idx = pd.Index(df.index).get_level_values(0)
# Set new index, but keep the multindex levels
df = df.set_index(pd.MultiIndex.from_tuples(((
        '{:%b}'.format(datetime.strptime(str(k), '%m')), 
        v 
) for k, v in idx), names=['month', 'day']), ['month', 'day']) 
print(df)

               data
month day          
Jan   10  -0.463804
      12   1.979072
      13   0.087430
Feb   1    0.928077
      20  -0.697795
      10  -0.275762

Update2:

I see that you've hard time to implement my answer into your code. This is why i've making this update to show you how you can implement my code within the code snipped you've added to your question. This is an example:

from datetime import datetime
import pandas as pd


start = '1/4/2020'
end = '3/5/2020'

data = pd.DataFrame()
full_dates = pd.date_range(start, end)
data = data.reindex(full_dates)
data['year'] = data.index.year
data['month'] = data.index.month
data['week'] = data.index.week
data['day'] = data.index.day
data.set_index('month', append=True, inplace=True)
data.set_index('week', append=True, inplace=True)
data.set_index('day', append=True, inplace=True)
df = data.groupby(['month', 'day']).mean()
idx = pd.Index(df.index).get_level_values(0)
df = df.set_index(pd.MultiIndex.from_tuples(((
    '{:%b}'.format(datetime.strptime(str(k), '%m')),
    v
) for k, v in idx), names=['month', 'day']), ['month', 'day'])
print(df)

Output:

           year
month day      
Jan   4    2020
      5    2020
      6    2020
      7    2020
      8    2020
...         ...
Mar   1    2020
      2    2020
      3    2020
      4    2020
      5    2020

[62 rows x 1 columns]
like image 41
Chiheb Nexus Avatar answered Oct 18 '22 21:10

Chiheb Nexus