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']
Related
I have a multi-index dataframe that is set up as follows:
index = pd.MultiIndex.from_product([['A','B','C'], ['x','y', 'z']])
multi_index = pd.DataFrame(np.nan, index=np.arange(10), columns=index)
Which produces the following output:
A B C
x y z x y z x y z
0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 NaN NaN NaN NaN NaN NaN NaN NaN NaN
6 NaN NaN NaN NaN NaN NaN NaN NaN NaN
7 NaN NaN NaN NaN NaN NaN NaN NaN NaN
8 NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 NaN NaN NaN NaN NaN NaN NaN NaN NaN
I am trying to fill the values of the multi-index data frame with values. As a toy example, what I've tried to do is change the value of ['A','x',0] as follows:
multi_index['A']['x'].loc[0] = 65.2
However, I receive a 'SettingWithCopyWarning', which makes sense to me. I've also tried
multi_index['A'].iloc[[1],0] = 65.2
and received the same warning.
Is there a way one can change the values of a multi-index dataframe on a entry-by-entry basis? I.E changing the 0th index of ['A','x']?
Try:
multi_index.loc[0, ('A', 'x')] = 65.2
You can use tuples with loc for index labelling to access your multiindex columns or rows.
Or you can use iloc like this using integer index position selection, for example 2 here is the third column:
multi_index.iloc[0, 2] = 70.3
Output:
A B C
x y z x y z x y z
0 65.2 NaN 70.3 NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 NaN NaN NaN NaN NaN NaN NaN NaN NaN
6 NaN NaN NaN NaN NaN NaN NaN NaN NaN
7 NaN NaN NaN NaN NaN NaN NaN NaN NaN
8 NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 NaN NaN NaN NaN NaN NaN NaN NaN NaN
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
Low S0.0 S1.0 S2.0 S3.0 S4.0 S5.0 S6.0 S7.0 S8.0 S9.0 S10.0 S11.0
0 55 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 60 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 78 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 12 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 77 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
I have the following code to check if any of the "S" columns are near to "close":
level=0.035
cond = np.isclose(df.Low, df['S0.0'], rtol=level) | np.isclose(df.Low, df['S1.0'], rtol=level) | ...
df['ST'] = np.where(cond, 100, 0)
But this looks too manual, is there some way to attribute all the S columns without specifically naming all of them? Also considering that these columns keep on changing so specifically calling every column sometimes gives an error. THANKS!
I think a solution can be as follows:
from itertools import repeat
from operator import or_
selected_columns = [c for c in df.columns if c.startswith('s')]
cond = None
for low_serie, sel_serie in zip(repeat(df.Low), [df[selected_column] for selected_column in selected_columns]):
if cond is None:
cond = np.isclose(low_serie, sel_serie, rtol=level)
continue
cond = or_(cond, np.isclose(low_serie, sel_serie, rtol=level))
You have to pay attention to the condition to select the columns names. I put as an example if c.startswith('s').
I’m trying to work with a very large csv file (15,500) that contains a Date, Time (HH:MM), Name, High, Low as the fields. Ideally this project will give me time bins for the data to show me what time the highest and lowest priced item tends to sell. The first step I’ve tried is to simply get the data into python and I’m encountering issues already. Before I can even begin to think about how to accomplish the end goal I’m stuck. I'm obviously so new at this, so please be kind...`
import numpy as np
my_data = np.genfromtxt('http://localhost:8888/edit/Downloads/sales.csv', delimiter= " , ", invalid_raise = False)
print (my_data)
output
[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan]
At this step I'd just like to see that my data has been imported correctly.
The next step I believe will be to find the max and min for each date, then figure out which time those happened.
Would that just be a for loop for the date, then an embedded for loop to find max and min?
I'd like a simple histograph of the time bins on the bottom to show if there is a time when the most expensive item sells and when the least expensive item sells (the data is already in 5min buckets).
There are spaces around the ",", try removing these. Additionally, try to add dtype=None, encoding='utf-8'. So try:
my_data = np.genfromtxt('Downloads/sales.csv', delimiter=",", dtype=None, encoding='utf-8')
Additionally, if the CSV has headers, you could try adding names=True. If you do that, you can access them by doing my_data['header_name']. (And (500,15) does not sound that large, numpy can deal with much larger arrays.)
And you should not use the Jupyter notebook url for loading that file. Just change the path to the proper filename.
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.