如果有两行是唯一对的行,我将尝试填充空白行。如果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
答案 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