Home > Blockchain >  pandas change all rows with Type X if 1 Type X Result = 1
pandas change all rows with Type X if 1 Type X Result = 1

Time:05-17

Here is a simple pandas df:

>>> df
   Type  Var1  Result
0     A     1     NaN
1     A     2     NaN
2     A     3     NaN
3     B     4     NaN
4     B     5     NaN
5     B     6     NaN
6     C     1     NaN
7     C     2     NaN
8     C     3     NaN
9     D     4     NaN
10    D     5     NaN
11    D     6     NaN

The object of the exercise is: if column Var1 = 3, set Result = 1 for all that Type.

This finds the rows with 3 in Var1 and sets Result to 1,

df['Result'] = df['Var1'].apply(lambda x: 1 if x == 3 else 0)

but I can't figure out how to then catch all the same Type and make them 1. In this case it should be all the As and all the Cs. Doesn't have to be a one-liner.

Any tips please?

CodePudding user response:

Create boolean mask and for True/False to 1/0 mapp convert values to integers:

df['Result'] = df['Type'].isin(df.loc[df['Var1'].eq(3), 'Type']).astype(int)

#alternative
df['Result'] = np.where(df['Type'].isin(df.loc[df['Var1'].eq(3), 'Type']), 1, 0)
print (df)
   Type  Var1  Result
0     A     1       1
1     A     2       1
2     A     3       1
3     B     4       0
4     B     5       0
5     B     6       0
6     C     1       1
7     C     2       1
8     C     3       1
9     D     4       0
10    D     5       0
11    D     6       0

Details:

Get all Type values if match condition:

print (df.loc[df['Var1'].eq(3), 'Type'])
2    A
8    C
Name: Type, dtype: object

Test original column Type by filtered types:

print (df['Type'].isin(df.loc[df['Var1'].eq(3), 'Type']))
0      True
1      True
2      True
3     False
4     False
5     False
6      True
7      True
8      True
9     False
10    False
11    False
Name: Type, dtype: bool

Or use GroupBy.transform with any for test if match at least one value, thi solution is slowier if larger df:

df['Result'] = df['Var1'].eq(3).groupby(df['Type']).transform('any').astype(int)
  • Related