Assuming ? could also be strings
import pandas as pd
import numpy as np
idx = ['A'] * 3 + ['B'] * 3 + ['C'] * 3
data = np.random.random_sample((9,2))
df = pd.DataFrame(index=idx, data=data[::], columns=['spend', 'recieved'])
df.index.name = 'name'
df.iloc[2, 1] = np.nan
df.iloc[1, 0] = 'ABCD'
df.iloc[4:6, 0] = np.nan
df
name spend recieved
A 0.197366 0.467532
A ABCD 0.256184
A 0.559562 NaN
B 0.59835 0.415382
B NaN 0.163827
B NaN 0.759888
C 0.897332 0.025344
C 0.782683 0.428465
C 0.201591 0.601339
Then
df = df.apply(pd.to_numeric, errors='coerce')
df['spend'] = df['spend'].groupby(level=0).transform(lambda x: x.fillna(x.mean()).fillna(0))
df['recieved'] = df['recieved'].groupby(level=0).transform(lambda x: x.fillna(x.mean()).fillna(0))
Which yields:
name spend recieved
A 0.197366 0.467532
A 0.378464 0.256184
A 0.559562 0.361858
B 0.598350 0.415382
B 0.598350 0.163827
B 0.598350 0.759888
C 0.897332 0.025344
C 0.782683 0.428465
C 0.201591 0.601339