У меня есть два df, таких как:
dfA
Out[191]:
a b c d
0 N M 1 3
1 S F 2 4
1 S F 2 4
И еще один такой вот:
dfM
Out[192]:
X Y d1 d2 d3
0 N M 0.1 0.2 0.3
1 S F 1.0 2.0 3.0
Теперь я хочу объединить эти два, чтобы получить df следующим образом:
a b c d e
0 N M 1 3 0.1
1 S F 2 4 1.0
1 S F 2 4 2.0
Объединенный df имеет значение из столбцов dfM d, которые заполняются в зависимости от количества повторений строк dfA. Как это сделать в python?
Вы можете использовать cumcount
для столбца счетчика-помощника для merge
с левым соединением, а также второй DataFrame преобразуется с помощью melt
:
dfA['groups'] = dfA.groupby(['a','b']).cumcount()
dfM1 = dfM.melt(['X','Y'], value_name='e')
dfM1['groups'] = dfM1.groupby(['X','Y']).cumcount()
print (dfM1)
X Y variable e groups
0 N M d1 0.1 0
1 S F d1 1.0 0
2 N M d2 0.2 1
3 S F d2 2.0 1
4 N M d3 0.3 2
5 S F d3 3.0 2
d = {'X':'a', 'Y':'b'}
df = (dfA.merge(dfM1.rename(columns=d), on=['a','b', 'groups'], how='left')
.drop(['variable','groups'],axis=1))
print (df)
a b c d e
0 N M 1 3 0.1
1 S F 2 4 1.0
2 S F 2 4 2.0
Одно из возможных решений - для каждой строки dfM
использовать их значения X
и Y
для фильтрации строк dfA
и установить столбец 'e'
на оставшиеся значения dfM
строк dfM
. Посмотрите пример ниже:
for i, row in dfM.iterrows():
d_values = row[2:].tolist()
indexes = list(dfA[(dfA.a == row.X) & (dfA.b == row.Y)].index)
dfA.loc[indexes, "e"] = d_values[:len(indexes)]
column d
.