Trouble Changing csv row based on column values in python3 and pandas - python-3.x

I am having issues trying to modify a value if columnA contains lets say 0,2,12,44,75,81 (looking at 33 different numerical values in columnA. If columnA contains 1 of the 33 vaules defined, i need to then change the same row of colulmnB to "approved".
I have tried this:
df[(df.columnA == '0|2|12|44|75|81')][df.columnB] = 'approved'
I get an error that there are none of index are in the columns but, i know that isn't correct looking at my csv file data. I must be searching wrong or using the wrong syntax.

As others have said, if you need the value in column A to match exactly with a value in the list, then you can use .isin. If you need a partial match, then you can convert to string dtypes and use .contains.
setup:
nums_to_match = [0,2,9]
df
A B
0 6 e
1 1 f
2 3 b
3 6 g
4 6 i
5 0 f
6 9 a
7 6 i
8 6 a
9 2 h
Exact match:
df.loc[df.A.isin(nums_to_match),'B']='approved'
df:
A B
0 6 e
1 1 f
2 3 b
3 6 g
4 6 i
5 0 approved
6 9 approved
7 6 i
8 6 a
9 2 approved
partial match:
nums_to_match_str = list(map(str,nums_to_match))
df['A']=df['A'].astype(str)
df.loc[df.A.str.contains('|'.join(nums_to_match_str),case=False,na=False),'B']='approved'
df
A B
0 1 h
1 4 c
2 6 i
3 7 d
4 3 d
5 9 approved
6 5 i
7 1 c
8 0 approved
9 5 d

Related

pandas fill 0s with mean based on rows that match a condition in another column

I have a dataframe like below in which I need to replace the 0s with the mean of the rows where the parent_key matches the self_key.
Input DataFrame: df= pd.DataFrame ({'self_key':['a','b','c','d','e','e','e','f','f','f'],'parent_key':[np.nan,'a','b','b','c','c','c','d','d','d'], 'value':[0,0,0,0,4,6,14,12,8,22],'level':[1,2,3,3,4,4,4,4,4,4]})
The row 3 has self_key of 'd' so I would need to replace its 0 value in column 'value' with the mean of rows 7,8,9 to fill with the correct value of 14. Since the lower levels feed into the higher levels I would need to do it from lowest level to highest to fill out the dataframe as well but when I do the below code it doesn't work and I get the error "ValueError: Grouper for '<class 'pandas.core.frame.DataFrame'>' not 1-dimensional". How can I fill in the 0s with the means from lowest level to highest?
df['value']=np.where((df['value']==0) & (df['level']==3), df['value'].groupby(df.where(df['parent_key']==df['self_key'])).transform('mean'), df['value'])
Input
self_key parent_key value level
0 a NaN 0 1
1 b a 0 2
2 c b 0 3
3 d b 0 3
4 e c 4 4
5 e c 6 4
6 e c 14 4
7 f d 12 4
8 f d 8 4
9 f d 22 4
My approach is to repeat the above code 3 times and change the level from 3 to 2 to 1, but its not working for even level 3.
Expected Ouput:
self_key parent_key value level
0 a NaN 11 1
1 b a 11 2
2 c b 8 3
3 d b 14 3
4 e c 4 4
5 e c 6 4
6 e c 14 4
7 f d 12 4
8 f d 8 4
9 f d 22 4
If I understand your problem correctly, you are trying to compute mean in a bottom-up fashion by filtering dataframe on certain keys. If so, then following should solve it:
for l in range(df["level"].max()-1, 0, -1):
df_sub = df[(df["level"] == l) & (df["value"] == 0)]
self_keys = df_sub["self_key"].tolist()
for k in self_keys:
df.loc[df_sub[df_sub["self_key"] == k].index, "value"] = df[df["parent_key"] == k]["value"].mean()
[Out]:
self_key parent_key value level
0 a 11 1
1 b a 11 2
2 c b 8 3
3 d b 14 3
4 e c 4 4
5 e c 6 4
6 e c 14 4
7 f d 12 4
8 f d 8 4
9 f d 22 4

Copy cells to new row

I have three columns, A, B and D
Column A and B have integer numbers that Im trying to map to column D which looks something like this:
A
B
C
D
1
3
7
2
4
9
I want to populate column C with column D's data, but I need to look like bellow:
A
B
C
D
1
3
7
7
2
4
7
9
3
3
7
4
4
7
5
3
7
1
4
9
2
3
9
3
4
9
4
3
9
5
4
9
I need to map column D and duplicate those numbers down to Column A and have Column C change every time Column A repeats to the first number, which in this case is 1

Append Dataframes of different dimensions

I have multiple dataframes with a different number of rows and columns respectively.
example:
df1:
a b c d
0 1 5 6
8 9 8 7
and df2:
g h
9 8
4 5
6 7
I have to append both the dataframes without a change in their dimensions.
The desired output should be one dataframe Result_df as:
a b c d
0 1 5 6
8 9 8 7
g h
9 8
4 5
6 7
Can anyone please help me to append dataframes without change in their structure.
Thank you

How to replenish a data frame based on another one?

Given two data frames. One contains a column of repeated values (a, in this case). The other contains what this value corresponds to (in this example, it corresponds to some "d" values). How do I efficiently replenish the first data frame with a new column, values in which correspond to some existent column, according to a rule recorded in the other data frame. Here is an example code that works really slow:
import pandas as pd
import numpy as np
d1 = pd.DataFrame(np.asarray([[1,2,3], [2,4,5], [3,4,5], [2,1,4], [3,4,5]]), columns = ['a', 'b', 'c'])
d2 = pd.DataFrame(np.asarray([[1,7], [2,8], [3,11]]), columns = ['a', 'd'])
d = np.empty((d1.shape[0],))
for i in range(d1.shape[0]):
temp = d2.loc[d2['a'] == d1.at[i,'a']]
d[i] = temp['d'].array[0]
d1['d'] = d
This is d1 original:
a b c
0 1 2 3
1 2 4 5
2 3 4 5
3 2 1 4
4 3 4 5
This is d2:
a d
0 1 7
1 2 8
2 3 11
This is a resultant d1:
a b c d
0 1 2 3 7
1 2 4 5 8
2 3 4 5 11
3 2 1 4 8
4 3 4 5 11
You're probably looking for pd.merge.
In your case, d1 = d1.merge(d2, on=['a'], how='left') should do the trick.
Another way is to use map and make only the values you need.
d1['d'] = d1['a'].map(d2.set_index('a')['d'])
d1
Output:
a b c d
0 1 2 3 7
1 2 4 5 8
2 3 4 5 11
3 2 1 4 8
4 3 4 5 11

Counting a group of columns on google spreadsheet

I have a couple of columns as shown below:
A B C D E
1 12 4 1
2 3 2 2
3 7
4 3 0 6
How would I be able to return a count of each column above so for example receive the result:
A B C D E
1 12 4 1
2 3 2 2
3 7
4 3 0 6
5 count:3 4 2 1
for each of the column. Im looking for a formula that would be able to do that in one cell(B5) returning a count for each of the columns, and avoid using fill handling as the data set is quite large
It's pretty easy, using Google Spreadsheet's functions:
=ArrayFormula(MMULT(TRANSPOSE(row(A1:A4)^0),--(len(A1:E4)>0)))
Or, if you want join them all:
=JOIN(", ",ArrayFormula(MMULT(TRANSPOSE(row(A1:A4)^0),--(len(A1:E4)>0))))

Resources