Take derivative of dataframe - python

I want to take the derivative of a dataframe row-wise. This is simply the difference: df_derived(i,j) = df(i,j)- df(i,j-1). Dataframe given below:
GRD1 GRD2 GRD3 GRD4 GRD5 GRD6 GRD7
0 1 6 5.0 9.0 1.0 7.0 9
1 5 8 NaN 8.0 NaN NaN 2
2 7 8 NaN NaN NaN 2.0 6
I am looking for:
GRD1 GRD2 GRD3 GRD4 GRD5 GRD6 GRD7
0 NaN 5.0 -1 4.0 -8.0 6.0 2.0
1 NaN 3.0 NaN NaN NaN NaN NaN
2 NaN 1.0 NaN NaN NaN NaN 4.0
But when I do: df.apply('diff',axis=1), result is different:
GRD1 GRD2 GRD3 GRD4 GRD5 GRD6 GRD7
0 NaN 5.0 NaN 4.0 -8.0 6.0 3.0
1 NaN 3.0 NaN NaN NaN NaN -6.0
2 NaN 1.0 NaN NaN NaN NaN -2.0
Notice column GR3 and GRD7 are different.
How to do this?

Let us try numpy diff
df[:]=np.hstack([np.ones((len(df),1))*np.nan,np.diff(df.values)])
df
GRD1 GRD2 GRD3 GRD4 GRD5 GRD6 GRD7
0 NaN 5.0 -1.0 4.0 -8.0 6.0 2.0
1 NaN 3.0 NaN NaN NaN NaN NaN
2 NaN 1.0 NaN NaN NaN NaN 4.0

Try cast all columns to float
df_final = df.astype(float).diff(axis=1)
Out[65]:
GRD1 GRD2 GRD3 GRD4 GRD5 GRD6 GRD7
0 NaN 5.0 -1.0 4.0 -8.0 6.0 2.0
1 NaN 3.0 NaN NaN NaN NaN NaN
2 NaN 1.0 NaN NaN NaN NaN 4.0

Related

I need to assing some record from one table to another according to some conditions

I have 2 data frames.
train:
rooms bedr bathr surface_t surface_c property_type
0 NaN 4.0 4.0 NaN NaN Casa
1 NaN 3.0 2.0 NaN NaN Apartamento
2 NaN NaN 2.0 NaN NaN Casa
3 NaN NaN 1.0 NaN NaN Otro
4 NaN NaN 2.0 NaN NaN Apartamento
... ... ... ... ... ... ...
197544 3.0 3.0 NaN NaN NaN Apartamento
197545 NaN NaN 1.0 NaN 17.0 Oficina
197546 NaN NaN 1.0 NaN NaN Otro
197547 NaN NaN 2.0 NaN NaN Casa
197548 NaN NaN 1.0 NaN NaN Apartamento
empty: with the mean value for each column according to the type of property
property_type rooms bedrooms bathrooms surface_total surface_covered
0 Apartamento 3.0 3.0 2.0 108.0 113.0
1 Casa 4.0 4.0 3.0 897.0 300.0
2 Finca 4.0 4.0 4.0 14925.0 30939.0
3 Local comercial 3.0 1.0 2.0 180.0 160.0
4 Lote 3.0 1.0 2.0 8979.0 13101.0
5 Oficina 3.0 1.0 2.0 144.0 121.0
6 Otro 6.0 5.0 3.0 991.0 1010.0
7 Parqueadero 4.0 2.0 NaN 496.0 545.0
In the dataframe Train for each of these columns: rooms, bedrooms, bathrooms, surface_total and surface_covered if the value is nan I need to fill it with the appropiate record of empty matching the property_type column.
e.g I need in the train.loc[0,'rooms] to be equal to 4.0 from empty (empty.loc[1,'rooms'],
train.loc[1,'rooms] == the value of empty.loc[0,'rooms'] that is 3.0 and so on.
I have been trying with double for cycles but I have not been able to do so. I'm frustrated now.

How to find the cumprod for dataframe by reserving the row values?

I have dataframe df:
0 1 2 3 4 5 6
Row Labels
2017 A1 2.0 2.0 NaN 2.0 NaN 2.0 NaN
2017 A2 2.0 2.0 2.0 NaN 2.0 2.0 NaN
2017 A3 2.0 2.0 2.0 2.0 2.0 2.0 NaN
2017 A4 2.0 2.0 2.0 2.0 2.0 2.0 NaN
2018 A1 2.0 2.0 2.0 2.0 NaN NaN NaN
2019 A2 2.0 2.0 2.0 NaN NaN NaN NaN
2020 A3 2.0 2.0 NaN NaN NaN NaN NaN
2021 A4 2.0 NaN NaN NaN NaN NaN NaN
I have to find the cumprod of the dataframe by reversing row values:
I tried this code ;
df1 = df[::-1].cumprod(axis=1)[::-1]
i got output like this ,
0 1 2 3 4 5 6
Row Labels
2017 A1 2.0 4.0 NaN 8.0 NaN 16.0 NaN
2017 A2 2.0 4.0 8.0 NaN 16.0 32.0 NaN
2017 A3 2.0 4.0 8.0 16.0 32.0 64.0 NaN
2017 A4 2.0 4.0 8.0 16.0 32.0 64.0 NaN
2018 A1 2.0 4.0 8.0 16.0 NaN NaN NaN
2019 A2 2.0 4.0 8.0 NaN NaN NaN NaN
2020 A3 2.0 4.0 NaN NaN NaN NaN NaN
2021 A4 2.0 NaN NaN NaN NaN NaN NaN
But expected output is ;
0 1 2 3 4 5 6
Row Labels
2017 A1 16.0 8.0 NaN 4.0 NaN 2.0 NaN
2017 A2 32.0 16.0 8.0 NaN 4.0 2.0 NaN
2017 A3 64.0 32.0 16.0 8.0 4.0 2.0 NaN
2017 A4 64.0 32.0 16.0 8.0 4.0 2.0 NaN
2018 A1 16.0 8.0 4.0 2.0 NaN NaN NaN
2019 A2 8.0 4.0 2.0 NaN NaN NaN NaN
2020 A3 4.0 2.0 NaN NaN NaN NaN NaN
2021 A4 2.0 NaN NaN NaN NaN NaN NaN
Thank You For Your Time :)
Use DataFrame.iloc with first : for select all rows and ::-1 for swapping by columns:
df1 = df.iloc[:, ::-1].cumprod(axis=1).iloc[:, ::-1]
print (df1)
0 1 2 3 4 5 6
Row Labels
2017 A1 16.0 8.0 NaN 4.0 NaN 2.0 NaN
2017 A2 32.0 16.0 8.0 NaN 4.0 2.0 NaN
2017 A3 64.0 32.0 16.0 8.0 4.0 2.0 NaN
2017 A4 64.0 32.0 16.0 8.0 4.0 2.0 NaN
2018 A1 16.0 8.0 4.0 2.0 NaN NaN NaN
2019 A2 8.0 4.0 2.0 NaN NaN NaN NaN
2020 A3 4.0 2.0 NaN NaN NaN NaN NaN
2021 A4 2.0 NaN NaN NaN NaN NaN NaN

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 long to wide with values filled based on answer

I am trying to convert a dataframe from long to wide, but Im not sure how to convert it to the format below. What am I missing?
d = {'vote': [100, 50,1,23,55,67,89,44],
'vote2': [10, 2,18,26,77,99,9,40],
'ballot1': ['a','b','a','a','b','a','a','b'],
'voteId':[1,2,3,4,5,6,7,8]}
df1=pd.DataFrame(d)
#########################################################
dftemp=df1
#####FORMATTING DATA
dftemp=pd.DataFrame(dftemp.reset_index())
dflw= dftemp.set_index(['voteId','vote','ballot1'])
dflw=dflw.unstack()
dflw.columns = dflw.columns.droplevel(0).rename('')
dflw=pd.DataFrame(dflw)
print(dflw)
MY CURRENT OUTPUT:
a b a b
voteId vote
1 100 0.0 NaN 10.0 NaN
2 50 NaN 1.0 NaN 2.0
GOAL:
voteid (ballot1=a)vote (ballot1=b)vote (ballot1=a)vote2 (ballot1=b)vote2
1 100 NaN 10 NaN
2 NaN 50 NaN 2
I am starting from df1
s=df1.set_index(['voteId','ballot1']).unstack()
s.columns=s.columns.map('(ballot1={0[1]}){0[0]}'.format)
s
Out[1120]:
(ballot1=a)vote (ballot1=b)vote (ballot1=a)vote2 (ballot1=b)vote2
voteId
1 100.0 NaN 10.0 NaN
2 NaN 50.0 NaN 2.0
3 1.0 NaN 18.0 NaN
4 23.0 NaN 26.0 NaN
5 NaN 55.0 NaN 77.0
6 67.0 NaN 99.0 NaN
7 89.0 NaN 9.0 NaN
8 NaN 44.0 NaN 40.0

Categories

Resources