分享:
方法一:
如果现在要把A中有且B中没有的数据,也就是新增部分,加到B表中去,该如何操作呢?
其实就是A与B求差集(A-C)后,再与B求并集
在上面的基础上进行如下操作 res = pd.merge(B,chaji, on=['学号','年龄','成绩'], how='outer') res 输出: 学号 年龄 成绩 0 1 23 89 1 2 22 90 2 3 34 67 3 4 33 88 4 5 12 78 5 6 27 98 6 0 20 无 7 7 28 90
方法二:A+B后,选择性看是否需要去重
直接求A与B 的并集,如果B中与A中字段数据不一致,需要按字段将数据去重,去重的时候,默认保留上一行,不保证数据准确性,最好A与B的表头一致。
dataA = {'学号':['1', '20', '3','4','5','6'],'年龄':['23','000','34','33','12','27'],'成绩':['89','90','67','88','78','98']} B = pd.DataFrame(dataA) dataB = {'学号':['0','1', '20', '3','4','5','7'],'年龄':['20','23','22','34','33','12','28'],'成绩':['无','89','90','67','88','78','90']} A = pd.DataFrame(dataB) print(A) print(B) 输出:可以注意到B中明显有一个错误数据——学号:20 A 学号 年龄 成绩 0 0 20 无 1 1 23 89 2 20 22 90 3 3 34 67 4 4 33 88 5 5 12 78 6 7 28 90 B 学号 年龄 成绩 0 1 23 89 1 20 000 90 2 3 34 67 3 4 33 88 4 5 12 78 5 6 27 98 # A与B求并集 res = pd.merge(B,A, on=['学号','年龄','成绩'], how='outer') res 输出: 学号 年龄 成绩 0 1 23 89 1 20 000 90 2 3 34 67 3 4 33 88 4 5 12 78 5 6 27 98 6 0 20 无 7 20 22 90 8 7 28 90 #去重,如果数据重复,自动保存上边那条,不保证结果准确性 res1 = res.drop_duplicates(['学号']) res1 输出: 学号 年龄 成绩 0 1 23 89 1 20 000 90 2 3 34 67 3 4 33 88 4 5 12 78 5 6 27 98 6 0 20 无 8 7 28 90
去除重复行
#原始数据 dataA = {'学号':['0','1','0','1','0','1'],'年龄':['20','23','20','23','20','24'],'成绩':['89','90','89','90','89','96']} df = pd.DataFrame(dataA) 输出: 学号 年龄 成绩 0 0 20 89 1 1 23 90 2 0 20 89 3 1 23 90 4 0 20 89 5 1 24 96
- 删除所有重复行
注意:必须每一列数据都一样才会删除
---删除所有重复行--- df_res = df.drop_duplicates() 输出: 学号 年龄 成绩 0 0 20 89 1 1 23 90 5 1 24 96
- 删除指定列重复的数据
最后只保留学号去重后,最上边的数据,学号为“1”,年龄为“24”的数据也被删除
---删除“学号”列重复的数据--- res = df.drop_duplicates(['学号']) res 输出: 学号 年龄 成绩 0 0 20 89 1 1 23 90
- 保留最后出现的值,使用关键字keep=‘last’
保留了学号为“1”,年龄为“24”那行
也可以按照多列去重
---去重后,保留最后一次出现的数据--- res = df.drop_duplicates(['学号'], keep='last') res 输出: 学号 年龄 成绩 4 0 20 89 5 1 24 96 #按照多列去重 res = df.drop_duplicates(['学号', '年龄'], keep='last') res 输出: 学号 年龄 成绩 3 1 23 90 4 0 20 89 5 1 24 96
透视
数据透视表是Excel的另一个神器,本质上是一系列的表格重组整合的过程。这里用的案例来自知乎,Excel数据透视表有什么用途:(https://www.zhihu.com/question/22484899/answer/39933218 )
问题:需要汇总各个区域,每个月的销售额与成本总计,并同时算出利润
通过Excel的数据透视表的操作最终实现了下面这样的效果:
python实现:对于这样的分组的任务,首先想到的就是pandas的groupby,代码写起来也简单,思路就是把刚才Excel的点鼠标的操作反映到代码命令上:
df = pd.read_excel('test.xlsx', sheet_name='销售统计表') df['订购月份'] = df['订购日期'].apply(lambda x:x.month) df2 = df.groupby(['订购月份', '所属区域'])[['销售额', '成本']].agg('sum') df2['利润'] = df2['销售额'] - df2['成本'] df2 Out[]: 销售额 成本 利润 订购月份 所属区域 1 南京 134313.61 94967.84 39345.77 常熟 177531.47 163220.07 14311.40 无锡 316418.09 231822.28 84595.81 昆山 159183.35 145403.32 13780.03 苏州 287253.99 238812.03 48441.96 2 南京 187129.13 138530.42 48598.71 常熟 154442.74 126834.37 27608.37 无锡 464012.20 376134.98 87877.22 昆山 102324.46 86244.52 16079.94 苏州 105940.34 91419.54 14520.80 ... ... ... 11 南京 286329.88 221687.11 64642.77 常熟 2118503.54 1840868.53 277635.01 无锡 633915.41 536866.77 97048.64 昆山 351023.24 342420.18 8603.06 苏州 1269351.39 1144809.83 124541.56 12 南京 894522.06 808959.32 85562.74 常熟 324454.49 262918.81 61535.68 无锡 1040127.19 856816.72 183310.48 昆山 1096212.75 951652.87 144559.87 苏州 347939.30 302154.25 45785.05 [60 rows x 3 columns]
也可以使用pandas里的pivot_table函数来实现:
df3 = pd.pivot_table(df, values=['销售额', '成本'], index=['订购月份', '所属区域'] , aggfunc='sum') df3['利润'] = df3['销售额'] - df3['成本'] df3
pandas的pivot_table的参数index/ columns/ values和Excel里的参数是对应上的(当然,我这话说了等于没说,数据透视表里不就是行/列/值吗还能有啥。)
groupby的功能很全面,内置了很多aggregate函数,能够满足大部分的基本需求,如果你需要一些其他的函数,可以搭配使用apply和lambda。
格式调整
修改列宽
- 只修改Jupyter notebook显示,可以使用Style功能,对导出表无影响
### Test data df.style.set_properties(subset=['Name'], **{'width': '200px'}) #输出结果如下:
- 修改导出表列宽
python修改导出excel列宽
合并单元格
df.merge_cells(‘A1:F1’)
绘图
因为Excel画出来的图能够交互,能够在图上进行一些简单操作,所以这里用的python的可视化库是plotly,开始之前,首先加载plotly包。
import plotly.offline as off import plotly.graph_objs as go off.init_notebook_mode()
柱状图
excel画的:
df = pd.read_excel("plot.xlsx", sheet_name='高等教育入学率') trace1 = go.Bar( x=df['国家'], y=df[1995], name='1995', opacity=0.6, marker=dict( color='powderblue' ) ) trace2 = go.Bar( x=df['国家'], y=df[2005], name='2005', opacity=0.6, marker=dict( color='aliceblue', ) ) trace3 = go.Bar( x=df['国家'], y=df[2014], name='2014', opacity=0.6, marker=dict( color='royalblue' ) ) layout = go.Layout(barmode='group') data = [trace1, trace2, trace3] fig = go.Figure(data, layout) off.plot(fig)
雷达图
用Excel画的:
df = pd.read_excel('plot.xlsx', sheet_name='政治治理') theta = df.columns.tolist() theta.append(theta[0]) names = df.index df[''] = df.iloc[:,0] df = np.array(df) trace1 = go.Scatterpolar( r=df[0], theta=theta, name=names[0] ) trace2 = go.Scatterpolar( r=df[1], theta=theta, name=names[1] ) trace3 = go.Scatterpolar( r=df[2], theta=theta, name=names[2] ) trace4 = go.Scatterpolar( r=df[3], theta=theta, name=names[3] ) data = [trace1, trace2, trace3, trace4] layout = go.Layout( polar=dict( radialaxis=dict( visible=True, range=[0,1] ) ), showlegend=True ) fig = go.Figure(data, layout) off.plot(fig)
画起来比Excel要麻烦得多。
总体而言,如果画简单基本的图形,用Excel是最方便的,如果要画高级一些的或者是需要更多定制化的图形,使用python更合适。