Pandas Pivot Table Subsetting - python

My pivot table looks like this:
Symbol DIA QQQ SPY XLE DIA QQQ SPY XLE DIA QQQ \
Open Open Open Open High High High High Low Low
Date
19930129 NaN NaN 29.083294 NaN NaN NaN 29.083294 NaN NaN NaN
19930201 NaN NaN 29.083294 NaN NaN NaN 29.269328 NaN NaN NaN
19930202 NaN NaN 29.248658 NaN NaN NaN 29.352010 NaN NaN NaN
19930203 NaN NaN 29.372680 NaN NaN NaN 29.662066 NaN NaN NaN
19930204 NaN NaN 29.744748 NaN NaN NaN 29.827430 NaN NaN NaN
Symbol SPY XLE DIA QQQ SPY XLE DIA \
Low Low Close Close Close Close Total Volume
Date
19930129 28.938601 NaN NaN NaN 29.062624 NaN NaN
19930201 29.083294 NaN NaN NaN 29.269328 NaN NaN
19930202 29.186647 NaN NaN NaN 29.331340 NaN NaN
19930203 29.352010 NaN NaN NaN 29.641396 NaN NaN
19930204 29.414021 NaN NaN NaN 29.765419 NaN NaN
Symbol QQQ SPY XLE
Total Volume Total Volume Total Volume
Date
19930129 NaN 15167 NaN
19930201 NaN 7264 NaN
19930202 NaN 3043 NaN
19930203 NaN 8004 NaN
19930204 NaN 8035 NaN
How does one go about subsetting for a particular day and for a particular column value, say Closing prices for all symbols?
19930129 NaN NaN 29.062624 NaN
i tried pt['Close'], but it didn't seem to work. Only pt['SPY'] gives me the whole table values for symbol SPY.

An alternative is to use xs, "cross-section":
In [21]: df.xs(axis=1, level=1, key="Open")
Out[21]:
Symbol DIA QQQ SPY XLE
Date
19930129 NaN NaN 29.083294 NaN
19930201 NaN NaN 29.083294 NaN
19930202 NaN NaN 29.248658 NaN
19930203 NaN NaN 29.372680 NaN
19930204 NaN NaN 29.744748 NaN
In [22]: df.xs(axis=1, level=1, key="Open").loc[19930129]
Out[22]:
Symbol
DIA NaN
QQQ NaN
SPY 29.083294
XLE NaN
Name: 19930129, dtype: float64
This is somewhat less powerful that unutbu's answer (using IndexSlice).

You could use pd.IndexSlice:
pt = pt.sortlevel(axis=1)
pt.loc['19930129', pd.IndexSlice[:,'Close']]
Using IndexSlicer requires the selection axes are fully lexsorted, hence the call to sortlevel.
Alternatively, slice(None) could also be used to select everything from the first column index level:
pt = pt.sortlevel(axis=1)
pt.loc['19930129', (slice(None), 'Close')]
To select the ith row, but select the columns by label, you could use
pt.loc[pt.index[i], (slice(None), 'Close')]
Or, you could use pt.ix as Andy Hayden suggests, but be aware that if pt has
an integer-valued index, then pt.ix performs label-based row indexing, not
ordinal indexing.
So as long as 19930129 (and the other index values) are not integers -- i.e. pt.index is not a Int64Index -- you could use
pt.ix[i, (slice(None), 'Close')]
Note that chained indexing, such as
pt.iloc[i].loc[(slice(None), 'Close')]
should be avoided when performing assignments, since assignment with chained indexing may fail to modify pt.

Related

How to remove rows that include partially Nan values without taking specific part of the row into account?

I am working with multiple big data frames. I want to remove their NaN parts automatically to ease the data cleansing process. Data is collected from a camera or radar feed, but the part of the data I need is when a specific object comes into the view horizon of the camera/ radar. So, the data file (frame) looks like below, and has lots of NaN values:
total in seconds datetime(utc) channels AlviraPotentialDronePlots_timestamp AlviraPotentialDronPlot_id ...
0 1601381457 2020-09-29 12:10:57 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 1601381459 2020-09-29 12:10:59 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 1601381460 2020-09-29 12:11:00 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 1601381461 2020-09-29 12:11:01 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 1601381463 2020-09-29 12:11:03 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... Useful data is here ... ... ... ... ... ... ... ... ...
623 1601382249 2020-09-29 12:24:09 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
624 1601382250 2020-09-29 12:24:10 NaN NaN NaN NaN NaN NaN NaN NaN ... 51.521264 5.858627 5.0 NaN NaN SearchRadar 0.0 0.0 NaN NaN
625 1601382251 2020-09-29 12:24:11 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
I have removed the columns with all NaN values using:
df = df.dropna(axis=1, how='all')
Now, I want to remove rows that contain all NaN. However, since total in seconds and datetime(utc) are always present in the file, I cannot use the following command:
df = df.dropna(axis=0, how='all')
Also, I cannot use how='any', because that would remove parts of the useful data too (the useful data contains some NaN values which I will fill later). I have to use the dropna() in a way that it does not take the total in seconds and datetime(utc) into account, but if all other fields are NaNs, then removes the whole row.
The closest I came to solving this problem was the command mentioned in this link, but I guess I am not enough familiar with Python to be able to formulate the following logic:
if in one row field != [is not] 'total in seconds' | [or] 'datetime(utc)' & [and] other fields == [is] 'NaN' then remove the row
I tried writing this with for loop too, but I was not successful. Can someone help me with this?
Thanks in advance.
You can check all columns without total in seconds, datetime(utc) by subset parameter with Index.difference:
cols = ['total in seconds','datetime(utc)']
checked = df.columns.difference(cols)
df = df.dropna(subset=checked, how='all')
If your number of columns is constant, you can use the parameter thresh.
Lets say you have 50 columns, you could put the thresh at 48 if you have 2 columns that are never empty.
For more, check https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.dropna.html

How to remove multi index from dataframe in python?

I have a data frame
purchase_count
Scrips 1STCUS 20MICRONS 21STCENMGM 3MINDIA
Client_id
A100027 NaN NaN NaN NaN
A100074 NaN NaN NaN NaN
A100077 NaN NaN NaN NaN
A100088 NaN NaN NaN NaN
A100091 NaN NaN NaN NaN
This dataframe is a result of pd.pivot_table and is getting created as multi index .Also output of df_matrix.columns is
MultiIndex(levels=[['purchase_count'], ['1STCUS', '20MICRONS', '21STCENMGM', '3IINFOTECH', '3MINDIA']])
How to remove multi indexing in which I want my output to be
1STCUS 20MICRONS 21STCENMGM 3MINDIA
A100027 NaN NaN NaN NaN
A100074 NaN NaN NaN NaN
A100077 NaN NaN NaN NaN
A100088 NaN NaN NaN NaN
A100091 NaN NaN NaN NaN
You can use MultiIndex.droplevel:
df.columns = df.columns.droplevel(0)
Another solution should be changed pivot_table, obviosly remove [] around ['purchase_count']

Python Pandas Datetime and dataframe indexing issue

I have a datetime issue where I am trying to match up a dataframe
with dates as index values.
For example, I have dr which is an array of numpy.datetime.
dr = [numpy.datetime64('2014-10-31T00:00:00.000000000'),
numpy.datetime64('2014-11-30T00:00:00.000000000'),
numpy.datetime64('2014-12-31T00:00:00.000000000'),
numpy.datetime64('2015-01-31T00:00:00.000000000'),
numpy.datetime64('2015-02-28T00:00:00.000000000'),
numpy.datetime64('2015-03-31T00:00:00.000000000')]
Then I have dataframe with returndf with dates as index values
print(returndf)
1 2 3 4 5 6 7 8 9 10
10/31/2014 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
11/30/2014 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Please ignore the missing values
Whenever I try to match date in dr and dataframe returndf, using the following code for just 1 month returndf.loc[str(dr[1])],
I get an error
KeyError: 'the label [2014-11-30T00:00:00.000000000] is not in the [index]'
I would appreciate if someone can help with me on how to convert numpy.datetime64('2014-10-31T00:00:00.000000000') into 10/31/2014 so that I can match it to the data frame index value.
Thank you,
Your index for returndf is not a DatetimeIndex. Make is so:
returndf = returndf.set_index(pd.to_datetime(returndf.index))
Your dr is a list of Numpy datetime64 objects. That bothers me:
dr = pd.to_datetime(dr)
Your sample data clearly shows that the index of returndf does not include all the items in dr. In that case, use reindex
returndf.reindex(dr)
1 2 3 4 5 6 7 8 9 10
2014-10-31 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-11-30 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-12-31 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2015-01-31 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2015-02-28 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2015-03-31 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

How can I refer to a column with a number as its name in a pandas dataframe?

I created a square dataframe in which the columns' names are its indices. See below for an example:
matrix
Out[75]:
24787 24798 24799 24789 24790 24791 24793 24797 24794 24796 24795 24788
24787 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
24798 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
24799 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
24789 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
24790 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
24791 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
...
I want to refer to each column, but matrix['24787'] returns KeyError: '24787' and matrix.24787 returns SyntaxError: invalid syntax. How do I refer to my column?
If the column names are integers (not strings), you can select a specific column with the specific integer value:
matrix[24787]
or, using the loc label selector,
matrix.loc[:, 24787]
If you want to select by index number, you can use iloc. For example, matrix.iloc[:, 0] selects the first column.

Pandas.DataFrame select by interval of indexes

I would like to know, in a pythonic way, how could I select elements in the Pandas.Dataframe inside a given interval in their indexes. Basically I wish to know if there is a command like pandas.Series.between for DataFrame.index .
example:
df1 = pd.DataFrame(x, index=(1,2,...,100000000), columns=['A','B','C'])
df2 = df1.between(start=10, stop=100000)
I think it is curious not easily finding anything related to this.
You can just use the subscript notation with loc which is label based indexing:
In [3]:
df2 = df1.loc[10:100000]
df2
Out[3]:
A B C
10 NaN NaN NaN
11 NaN NaN NaN
12 NaN NaN NaN
13 NaN NaN NaN
14 NaN NaN NaN
15 NaN NaN NaN
.....
99994 NaN NaN NaN
99995 NaN NaN NaN
99996 NaN NaN NaN
99997 NaN NaN NaN
99998 NaN NaN NaN
99999 NaN NaN NaN
10000 NaN NaN NaN
[99991 rows x 3 columns]
You also mention not being able to find documentation about this but it's pretty easy to find and clear: http://pandas.pydata.org/pandas-docs/stable/indexing.html

Categories

Resources