Как эффективно изменить значения в фрейме данных на основе значений из другого фрейма? - PullRequest
0 голосов
/ 03 октября 2018

У меня есть 2 кадра данных, например:

import pandas as pd
data1 = {'Col1':['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],
        'Col2':[3.409836, 2.930693, 2.75, 3.140845, 2.971429, 2.592593, 2.6, 3.1875, 2.857143, 0.714286]}
df1 = pd.DataFrame(data1, columns=['Col1', 'Col2'])

data2 = {'Col1':['B', 'F', 'I'],
         'Col2':[23.45, 32.57, 19.85]}
df2 = pd.DataFrame(data2, columns=['Col1', 'Col2'])

enter image description here

Я хочу изменить значения Col2 в df1 с помощьюзначения от df2.Это мой код для этого:

for i in range(len(df2)):
    for j in range(len(df1)):
        if df2['Col1'][i]==df1['Col1'][j]:
            df1['Col2'][j]=df2['Col2'][i]

Код работает:

enter image description here

Но проблема в том, что этот код будетбыть медленным для больших фреймов данных, поскольку это имеет сложность O(len(df1)*len(df2)).Как объединить 2 кадра данных более быстрым и эффективным способом?

Я попытался объединить кадры данных с помощью внешнего объединения, но он не дает правильного результата - он сохраняет оба значения:

pd.merge(df1, df2, how='outer')

enter image description here

Внутреннее объединение создает пустой кадр данных, левое объединение создает тот же кадр данных, что и df1, а правое объединение создает тот же кадр данных, что и df2.

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

попробуйте этот код:

df4=df3.Col3.isnull()
df3=pd.merge(df1, df2,how='outer')
df4=df3[df3.Col3.isnull()]
df5=df3[df3.Col3.notnull()]
df5.Col2=df5.Col3
df6=df4.append(df5)
df6=df6.drop('Col3',axis=1)

df6 - это выход, который вы ищете.

0 голосов
/ 03 октября 2018

При работе только с одним столбцом используйте map:

df1['Col2'] = df1['Col1'].map(df2.set_index('Col1')['Col2']).fillna(df1['Col2'])
print (df1)
  Col1       Col2
0    A   3.409836
1    B  23.450000
2    C   2.750000
3    D   3.140845
4    E   2.971429
5    F  32.570000
6    G   2.600000
7    H   3.187500
8    I  19.850000
9    J   0.714286

Если возможно несколько столбцов, используйте merge с левым соединением и указанным столбцом Col1:

cols = df1.columns.difference(['Col1'])
orig_cols = [f'{x}_' for x in cols]

df = pd.merge(df1, df2, how='left', on='Col1', suffixes=('_',''))
print (df)
  Col1     Col2_   Col2
0    A  3.409836    NaN
1    B  2.930693  23.45
2    C  2.750000    NaN
3    D  3.140845    NaN
4    E  2.971429    NaN
5    F  2.592593  32.57
6    G  2.600000    NaN
7    H  3.187500    NaN
8    I  2.857143  19.85
9    J  0.714286    NaN

Затем замените отсутствующие значения добавленного столбца исходными столбцами и в последний раз удалите их:

df[cols] = df[cols].fillna(df[orig_cols].rename(columns=lambda x: x.strip('_')))
df = df.drop(orig_cols, axis=1)

print (df)
  Col1       Col2
0    A   3.409836
1    B  23.450000
2    C   2.750000
3    D   3.140845
4    E   2.971429
5    F  32.570000
6    G   2.600000
7    H   3.187500
8    I  19.850000
9    J   0.714286
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...