熊猫:当其他两列是唯一对时,从一列复制值

时间:2019-04-29 18:27:14

标签: python pandas pandas-groupby

如果有两行是唯一对的行,我将尝试填充空白行。如果Col2为A1,则col2为A1且客户相同的任何行(即Cust1),则合并所有为true的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 :(得分:0)

创建您自己的函数,以确定每个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

这将处理在不同字段中重复值的情况:Version1中的'1, 2''1, 3'仍将返回'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)

答案 1 :(得分:0)

我认为这应该可行。 我以您的桌子为起点,并得到了预期的结果。

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

答案 2 :(得分:0)

您可以使用groupby和transform

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