Панды: копировать значения из одного столбца, когда два других столбца являются уникальными парами - PullRequest
2 голосов
/ 29 апреля 2019

Я пытаюсь заполнить пустые строки, если есть строки, в которых два столбца являются уникальными парами. Если Col2 равен A1, то все строки, где col2 - это A1, а клиент совпадает (то есть Cust1), объедините все значения Col3, если это так, и замените все строки на объединенный результат.

По сути, я запускаю скрипт для фильтрации по определенным строкам, но столбцы "Версия" пусты. Существуют значения для столбцов «Версия» в строках, которые не соответствуют критериям, поэтому я хочу объединить все данные «Версия», где «Клиент» и «Модель» представляют собой уникальную пару.

df = pd.read_excel(file, header=2)

grouped = df.groupby('Model').agg({'Version1':','.join,'Version2':','.join})

Пример таблицы

Customer        Model        Version1       Version2
Cust1           A1           1, 2           5
Cust1           A1           3              6
Cust1           A1           NaN            NaN
Cust2           A2           1              3
Cust2           A1           2              NaN
Cust2           A2           NaN            4

Конечный результат:

Customer        Model        Version1       Version2
Cust1           A1           1, 2, 3        5, 6
Cust1           A1           1, 2, 3        5, 6
Cust1           A1           1, 2, 3        5, 6
Cust2           A2           1              3, 4
Cust2           A1           2              NaN
Cust2           A2           1              3, 4

Ответы [ 3 ]

0 голосов
/ 29 апреля 2019

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

import pandas as pd
example = pd.read_excel('Book1.xlsx', sheet_name='example')
core = example[['Customer','Model']].drop_duplicates()
for index, row in core.iterrows():
    filtered_example = example[(example['Customer'] == row['Customer'])
                               & (example['Model'] == row['Model'])]
    list_v1 = list(filtered_example['Version1'].drop_duplicates().dropna())
    example.at[(example['Customer'] == row['Customer'])
                 & (example['Model'] == row['Model']),'Version1'] = str(list_v1)
    list_v2 = list(filtered_example['Version2'].drop_duplicates().dropna())
    example.at[(example['Customer'] == row['Customer'])
                 & (example['Model'] == row['Model']),'Version2'] = str(list_v2)
print(example)

Надеюсь, это поможет.BR

0 голосов
/ 29 апреля 2019

Вы можете использовать группирование и преобразование,

df[['Version1','Version2']] = df.groupby(['Customer','Model']).transform(lambda x: ', '.join(x.dropna()))

    Customer    Model   Version1    Version2
0   Cust1       A1      1, 2, 3     5, 6
1   Cust1       A1      1, 2, 3     5, 6
2   Cust1       A1      1, 2, 3     5, 6
3   Cust2       A2      1           3, 4
4   Cust2       A1      2   
5   Cust2       A2      1           3, 4
0 голосов
/ 29 апреля 2019

Создайте свою собственную функцию, чтобы определить все уникальные версии в каждой группе Customer-Model.Затем используйте transform, чтобы передать результат обратно в каждую строку этой группы.

Пример данных

import pandas as pd
import numpy as np
df = pd.DataFrame({'Customer': ['Cust1']*3+['Cust2']*3,
                   'Model': ['A1']*3 + ['A2', 'A1', 'A2'],
                   'Version1': ['1, 2', '3', np.NaN, '1', '2', np.NaN],
                   'Version2': ['5', '6', np.NaN, '3', np.NaN, '4']})

Код:

def my_join(x):
    x = x.dropna()
    if x.empty:
        return np.NaN
    else:
        return ', '.join(np.unique(x.str.split(',\s?').sum()))

gp = df.groupby(['Customer', 'Model'])
for col in ['Version1', 'Version2']:
    df[col] = gp[col].transform(my_join)

Вывод:

  Customer Model Version1 Version2
0    Cust1    A1  1, 2, 3     5, 6
1    Cust1    A1  1, 2, 3     5, 6
2    Cust1    A1  1, 2, 3     5, 6
3    Cust2    A2        1     3, 4
4    Cust2    A1        2      NaN   
5    Cust2    A2        1     3, 4

Это будет учитывать случаи, когда значения повторяются в пределахдругие поля: '1, 2' и '1, 3' в версии 1 будут по-прежнему возвращать '1, 2, 3' в качестве выходных данных:


Похоже, что у .transform(str.join) возникают проблемы при наличии нулевых ключей группировки.Таким образом, мы можем замаскировать их первыми, чтобы исправить ValueError:

m = df[['Customer', 'Model']].notnull().all(1)

gp = df[m].groupby(['Customer', 'Model'])
for col in ['Version1', 'Version2']:
    df.loc[m, col] = gp[col].transform(my_join)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...