I have data like this:
df = pd.DataFrame({
'nameset1_0': [np.nan, 'A', 'B', 'C', np.nan],
'nameset1_1': ['D', np.nan, 'E', 'F', 'G'],
'nameset1_2': ['H', np.nan, np.nan, np.nan, np.nan],
'nameset2_0': ['H', 'A', 'E', 'F', np.nan],
'nameset2_1': ['D', np.nan, np.nan, 'C', 'G'],
'nameset2_2': [np.nan, np.nan, 'B', np.nan, np.nan],
'nameset2_val_0': [6, 76, 7, 34, 30],
'nameset2_val_1': [33, 97, 73, 21, 45],
'nameset2_val_2': [53, 28, 47, 94, 34]
})
For nameset2, the values in each of the _0, _1, _2 suffix nameset2_val_ columns correspond to the name/label in the nameset2_ columns with the corresponding suffix.
There are the same set of values in each row between the nameset1_ and nameset2_ columns, but they're shuffled differently in each row.
What I need to do is create a set of value columns for nameset1 that correctly match the nameset2 values to the appropriate name in nameset1_. The output should look like this (I'm being as careful as I can but if you think there's an error here please drop a comment):
df = pd.DataFrame({
'nameset1_0': [np.nan, 'A', 'B', 'C', np.nan],
'nameset1_1': ['D', np.nan, 'E', 'F', 'G'],
'nameset1_2': ['H', np.nan, np.nan, np.nan, np.nan],
'nameset2_0': ['H', 'A', 'E', 'F', np.nan],
'nameset2_1': ['D', np.nan, np.nan, 'C', 'G'],
'nameset2_2': [np.nan, np.nan, 'B', np.nan, np.nan],
'nameset2_val_0': [6, 76, 7, 34, np.nan],
'nameset2_val_1': [33, np.nan, np.nan, 21, 45],
'nameset2_val_2': [np.nan, np.nan, 47, np.nan, np.nan],
'nameset1_val_0': [np.nan, 76, 47, 21, np.nan],
'nameset1_val_1': [33, np.nan, 7, 34, 45],
'nameset1_val_2': [6, np.nan, np.nan, np.nan, np.nan]
})
My insanely clunky code to try to handle this currently looks something like this, but it works inconsistently or not at all:
for i in list(range(3)):
df['nameset1_val_'+str(i)] = df[
['nameset1_'+str(i)]
+['nameset2_val_'+str(j) for j in list(range(3))]
].apply(
lambda row: [i for i,e in enumerate(row[1:]) if e==row[0]],
axis=1
).apply(lambda lst: lst.pop() if len(lst)==1 else np.nan)
prefix='nameset2_val_'
df['nameset1_val_'+str(i)] = df[
['nameset2_val_'+str(i) for i in list(range(3))]
].to_numpy()[df.index,
df.columns.get_indexer(
df['nameset1_val_'+str(i)].fillna(-1).astype(int).astype(str).radd(prefix)
)]