Без изменений в исходных значениях данных - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть пример кадра данных df, как указано ниже -

A  B
1  41
2  42
3  43
1  46
2  47
3  48
1  51
2  52
3  53

Моя текущая цель состоит в том, чтобы при определенном значении столбца A заменить все значения столбца B первым вхождением.Например, для A = 1, B = 41 является первым соответствующим значением.Итак, я должен заменить все остальные строки с A = 1 для столбца B как 41. По сути, я должен получить следующее:

A  B
1  41
2  42
3  43
1  41
2  42
3  43
1  41
2  42
3  43

Я попытался действовать следующим образом:

МЕТОД 1 -

a = df.A.unique()
for i in a:
    x = df.loc[df['A'] == i]
    x['B'] = x['B'].iloc[0]
    print(x)

При печати x это дает мне желаемый вывод как

    A   B
0   1  41
3   1  41
6   1  41
    A   B
1   2  42
4   2  42
7   2  42
    A   B
2   3  43
5   3  43
8   3  43

Но когда я проверяю фрейм данных dfопять же, абсолютно никаких изменений в значениях.

Я также попробовал следующую альтернативу -

МЕТОД - 2

def custom_function(df):
    x = df['B'].iloc[0]
    df['A'] = df['A']
    df.loc[:,['B']] = x
    return df['A']

for key, item in df.groupby('A'):
    item.apply(lambda x: custom_function(item))
    print(item)

При печати item это также дало мне желаемый вывод в виде -

    A   B
0   1  41
3   1  41
6   1  41
    A   B
1   2  42
4   2  42
7   2  42
    A   B
2   3  43
5   3  43
8   3  43

Но когда я проверяю значение фрейма данных df, без изменений совсем.Я предполагаю, что я работаю над копией кадра данных, а не над фактическим, но я не знаю, как решить эту проблему.

1 Ответ

0 голосов
/ 27 ноября 2018

Проблема в том, что вы создаете новую переменную внутри цикла с поверхностной копией данных и модифицируете ее.Изменения в исходном фрейме данных фактически не записываются, если вы сами не сделаете это с помощью df.loc.Другой, лучший вариант - векторизовать это, удалив цикл.

Вам понадобятся groupby и transform:

df = df.assign(B=df.groupby('A').B.transform('first')).sort_values('A')
print(df)
   A   B
0  1  41
3  1  41
6  1  41
1  2  42
4  2  42
7  2  42
2  3  43
5  3  43
8  3  43

Только для вашего понимания, этокак исправить вашу петлю:

for a in df.A.unique():
    m = df['A'] == a 
    df.loc[m, 'B'] = df.at[m.idxmax(), 'B']
...