1.append/assign/combine/update/concat/merge/join各自最适合使用的场景
- append与assign是行接
- combine/update是填充
- merge/join横向拼接
- merge_ordered和merge_asof的作用是什么?和merge是什么关系?
- merge_ordered:函数允许组合时间序列和其他有序数据。 特别是它有一个可选的fill_method关键字来填充/插入缺失的数据。
- merge_asof除了我们匹配最近的键而不是相等的键之外,其他的都类似于有序的left-join 。
对于左侧DataFrame中的每一行,我们选择右侧DataFrame中on键对应的值小于left的键对应的值的最后一行。
3.请构造一个多级索引与多级索引合并的例子,尝试使用不同的合并函数。
4.上文提到了连接的笛卡尔积,那么当连接方式变化时(inner/outer/left/right),这种笛卡尔积规则会相应变化吗?请构造相应例子。
ex 5-1
import pandas as pd
import numpy as np
df1 = pd.read_csv('data/Employee1.csv')
df2 = pd.read_csv('data/Employee2.csv')
# 每个公司有多少员工满足如下条件:既出现第一张表,又出现在第二张表
L = list(set(df1['Name']).intersection(set(df2['Name'])))
# 将所有不符合(a)中条件的行筛选出来,合并为一张新表,列名与原表一致
df_b1 = df1[~df1['Name'].isin(L)]
df_b2 = df2[~df2['Name'].isin(L)]
df_b = pd.concat([df_b1,df_b2]).set_index('Name')
# 现在需要编制所有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 L else 'N' for i in range(df1.shape[0])]
df2['重复'] = ['Y_2' if df2.loc[i,'Name'] in L 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 L:
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_b])
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()
ex5-2
import pandas as pd
import numpy as np
# 将两张表分别拆分为专业课与非专业课(结果为四张表)
df1 = pd.read_csv('data/Course1.csv')
df2 = pd.read_csv('data/Course2.csv')
df_a11,df_a12,df_a21,df_a22 =0,0,0,0
df_a11= df1.query('课程类别 in ["学科基础课","专业必修课","专业选修课"]')
df_a12= df1.query('课程类别 not in ["学科基础课","专业必修课","专业选修课"]')
df_a21= df2.query('课程类别 in ["学科基础课","专业必修课","专业选修课"]')
df_a22= df2.query('课程类别 not in ["学科基础课","专业必修课","专业选修课"]')
df_a11.head()
# 将两张专业课的分数表和两张非专业课的分数表分别合并
special = pd.concat([df_a11,df_a21])
common = pd.concat([df_a12,df_a22])
special.query('课程类别 not in ["学科基础课","专业必修课","专业选修课"]')
print(common.query('课程类别 in ["学科基础课","专业必修课","专业选修课"]')
# 不使用上面中的步骤,请直接读取两张表合并后拆分
df = pd.concat([df1,df2])
special2 = df.query('课程类别 in ["学科基础课","专业必修课","专业选修课"]')
common2 = df.query('课程类别 not in ["学科基础课","专业必修课","专业选修课"]')
(special.equals(special2),common.equals(common2))
# 专业课程中有缺失值吗,如果有的话请在完成(3)的同时,用组内(3种类型的专业课)均值填充缺失值后拆分
df['分数'] = df.groupby('课程类别').transform(lambda x: x.fillna(x.mean()))['分数']
print(df.isnull().all())
special3 = df.query('课程类别 in ["学科基础课","专业必修课","专业选修课"]')
common3 = df.query('课程类别 not in ["学科基础课","专业必修课","专业选修课"]')
参考博客
https://blog.csdn.net/laicikankna/article/details/105785055