Pandas Task5 合并

Pandas Task5 合并


五、问题与练习

  1. 问题
    【问题一】 请思考什么是append/assign/combine/update/concat/merge/join各自最适合使用的场景,并举出相应的例子。

append:主要用于添加行
assign:主要用于添加列
cobmine和update都是用于表的填充函数,可以根据某种规则填充¶
concat:主要用于两个DataFrame的行连接
merge:将两个pandas对象横向合并
join:将多个pandas对象横向拼接

【问题二】 merge_ordered和merge_asof的作用是什么?和merge是什么关系?
【问题三】 请构造一个多级索引与多级索引合并的例子,尝试使用不同的合并函数。
【问题四】 上文提到了连接的笛卡尔积,那么当连接方式变化时(inner/outer/left/right),这种笛卡尔积规则会相应变化吗?请构造相应例子。

  1. 练习
    【练习一】有2张公司的员工信息表,每个公司共有16名员工,共有五个公司,请解决如下问题:
    (a) 每个公司有多少员工满足如下条件:既出现第一张表,又出现在第二张表。
len(df['Name']) - df['Name'].nunique()

16

(b) 将所有不符合(a)中条件的行筛选出来,合并为一张新表,列名与原表一致。

list_name = list(df.groupby('Name')['Age'].count().index)
list_num = list(df.groupby('Name')['Age'].count().values)
dict_test = {
    
    }
for name, num in zip(list_name, list_num):
    try:
        dict_test[num].append(name)
    except:
        dict_test[num] = [name]
        
df_new = df.loc[df['Name'].isin(dict_test[1]), :]
df_new = df_new.sort_values(by='Name').reset_index().drop(columns='index')
df_new

在这里插入图片描述

© 现在需要编制所有80位员工的信息表,对于(b)中的员工要求不变,对于满足(a)条件员工,它们在某个指标的数值,取偏离它所属公司中满足(b)员工的均值数较小的哪一个,例如:P公司在两张表的交集为{p1},并集扣除交集为{p2,p3,p4},那么如果后者集合的工资均值为1万元,且p1在表1的工资为13000元,在表2的工资为9000元,那么应该最后取9000元作为p1的工资,最后对于没有信息的员工,利用缺失值填充。

df1 = pd.read_csv('../data/Employee1.csv')
df2 = pd.read_csv('../data/Employee2.csv')
df1['重复'] = ['Y_1' if df1.loc[i,'Name'] in dict_test[2] else 'N' for i in range(df1.shape[0])]
df2['重复'] = ['Y_2' if df2.loc[i,'Name'] in dict_test[2] else 'N' for i in range(df2.shape[0])]
df1 = df1.set_index(['Name','重复'])
df2 = df2.set_index(['Name','重复'])
df_c = pd.concat([df1,df2])
result = pd.DataFrame({
    
    'Company':[],'Name':[],'Age':[],'Height':[],'Weight':[],'Salary':[]})
group = df_c.groupby(['Company','重复'])
for i in dict_test[2]:
    first = group.get_group((i[0].upper(),'Y_1')).reset_index(level=1).loc[i,:][-4:]
    second = group.get_group((i[0].upper(),'Y_2')).reset_index(level=1).loc[i,:][-4:]
    mean = group.get_group((i[0].upper(),'N')).reset_index(level=1).mean()
    final = [i[0].upper(),i]
    for j in range(4):
        final.append(first[j] if abs(first[j]-mean[j])<abs(second[j]-mean[j]) else second[j])
    result = pd.concat([result,pd.DataFrame({
    
    result.columns.tolist()[k]:[final[k]] for k in range(6)})])
result = pd.concat([result.set_index('Name'),df_new])
for i in list('abcde'):
    for j in range(1,17):
        item = i+str(j)
        if item not in result.index:
            result = pd.concat([result,pd.DataFrame({
    
    'Company':[i.upper()],'Name':[item]
                 ,'Age':[np.nan],'Height':[np.nan],'Weight':[np.nan],'Salary':[np.nan]}).set_index('Name')])
result['Number'] = [int(i[1:]) for i in result.index]
result.reset_index().drop(columns='Name').set_index(['Company','Number']).sort_index()

【练习二】有2张课程的分数表(分数随机生成),但专业课(学科基础课、专业必修课、专业选修课)与其他课程混在一起,请解决如下问题:
(a) 将两张表分别拆分为专业课与非专业课(结果为四张表)。

df_c1 = pd.read_csv('../data/Course1.csv')
df_c2 = pd.read_csv('../data/Course2.csv')
# 表一中的专业课
df_c1_p = df_c1.loc[df_c1['课程类别'].isin(['学科基础课', '专业必修课', '专业选修课'])]
# 表二中的专业课
df_c2_p = df_c2.loc[df_c2['课程类别'].isin(['学科基础课', '专业必修课', '专业选修课'])]
# 表一中的非专业课
df_c1_np = df_c1.loc[~df_c1['课程类别'].isin(['学科基础课', '专业必修课', '专业选修课'])]
# 表二中的非专业课
df_c2_np = df_c2.loc[~df_c2['课程类别'].isin(['学科基础课', '专业必修课', '专业选修课'])]

(b) 将两张专业课的分数表和两张非专业课的分数表分别合并。

df_p = pd.concat([df_c1_p, df_c2_p])
df_np = pd.concat([df_c1_np, df_c2_np])

© 不使用(a)中的步骤,请直接读取两张表合并后拆分。

df = pd.concat([df_c1, df_c2])
# 专业课
df_p = df.loc[df['课程类别'].isin(['学科基础课', '专业必修课', '专业选修课'])]
# 非专业课
df_np = df.loc[~df['课程类别'].isin(['学科基础课', '专业必修课', '专业选修课'])]

(d) 专业课程中有缺失值吗,如果有的话请在完成(3)的同时,用组内(3种类型的专业课)均值填充缺失值后拆分。

df['分数'] = df.groupby('课程类别')['分数'].transform(lambda x: x.fillna(x.mean()))
df_p = df.loc[df['课程类别'].isin(['学科基础课', '专业必修课', '专业选修课'])]
df_np = df.loc[~df['课程类别'].isin(['学科基础课', '专业必修课', '专业选修课'])]

猜你喜欢

转载自blog.csdn.net/weixin_44424296/article/details/105871499
今日推荐