Create new column with data that has same column
This is approach(worst) I can only think of :
r = df.groupby('building')['name'].agg(dict)
df['in_building_with'] = df.apply(lambda x: [r[x['building']][i] for i in (r[x['building']].keys()-[x.name])], axis=1)
df:
name building in_building_with
0 a blue [c, e]
1 b white []
2 c blue [a, e]
3 d red [f]
4 e blue [a, c]
5 f red [d]
Approach:
- Make a dictionary which will give your indices where the building occurs.
building
blue {0: 'a', 2: 'c', 4: 'e'}
red {3: 'd', 5: 'f'}
white {1: 'b'}
dtype: object
- subtract the index of the current building from the list since you are looking at the element other than it to get the indices of appearance.
r[x['building']].keys()-[x.name]
- Get the values at those indices and make them into a list.
If order is not important, you could do:
# create groups
groups = df.groupby('building').transform(dict.fromkeys).squeeze()
# remove value from each group
df['in_building_with'] = [list(group.keys() - (e,)) for e, group in zip(df['name'], groups)]
print(df)
Output
name building in_building_with
0 a blue [e, c]
1 b white []
2 c blue [e, a]
3 d red [f]
4 e blue [a, c]
5 f red [d]
May be a little late but this is more concise way and without iterating over objects(for-loops).
With thanks to @Pygirl answer and as an improvement to it:
r = df.groupby('building')['name'].agg(set)
df['in_building_with']= df.apply( lambda x: list(r[x['building']] - {x['name']}) , axis=1)
print(df)
Output:
name building in_building_with
0 a blue [e, c]
1 b white []
2 c blue [e, a]
3 d red [f]
4 e blue [a, c]
5 f red [d]