文章数据
收藏(次)
【python数据分析】第八章 数据规整-3
合并重叠数据
concat, merge 都是对数据进行扩展,合并,数据之间没有重合。即两边的数据都有各自的位置。
这里说的合并就会发生两个数据想要占用同一个位置,这时要决定这个位置到底给哪个数据,
另一没位置相当于丢弃了
--------------------------------------------------------------------------------
a = pd.Series([np.nan, 2, np.nan, 3, 4, np.nan], index=['a', 'b', 'c', 'd', 'e', 'f'])
b = pd.Series([10,11,12,13,14,np.nan],index=['a', 'b', 'c', 'd', 'e', 'f'])
--------------------------------------------------------------------------------
np 的方法,要求, a,b 必须是同型的,也就是长度需要相等。
np.where(pd.isnull(a), b, a)
如果条件成立使用 b, 否则使用a,这样就解决了两个数据占用同一个位置使,位置给谁的问题
--------------------------------------------------------------------------------
使用 pands 的 combine 方法
a = pd.Series([np.nan, 2, np.nan, 3, 4, np.nan], index=['a', 'b', 'c', 'd', 'e', 'f'])
b = pd.Series([10,11,12,13,np.nan,15,16],index=['a', 'b', 'c', 'd', 'e', 'f','g'])
没有要求 a,b 同型
b.combine_first(a) # b 中的 非NA 数据 和 a 中有 b 中没有的数据组合成新的数组
a.combine_first(b) # a 中的 非NA 数据,b 中特有的数据 都会出现再 新数组中
--------------------------------------------------------------------------------
combine 可以传入一个fun回调,自己决定怎么处理,
参数是两个数组的相同索引的数据(遍历次数是最长数组长度),没有该索引的传入 NA
a.combine(b,func=lambda x,y: y if pd.isnull(x) else x)
--------------------------------------------------------------------------------
DataFrame 数据的合并:
df1 = pd.DataFrame({'aa': [1., np.nan, 5., np.nan],
'b': [np.nan, 2., np.nan, 6.],
'c': range(2, 18, 4)})
df2 = pd.DataFrame({'a': [5., 4., np.nan, 3., 7.],
'b': [np.nan, 3., 4., 6., 8.]})
df1.combine_first(df2): 能合并的要求是 columns 和 index 都必须相同,如果不相同
就会把他们进行水平和垂直方向上扩展。而不会位置重回。
df1.combine_first(df2): 作用是 df1 中 NA 的数据会到 df2 中找相同位置的数据进行填充。
得到的结果是 行数是 df1,df2的行的较大的那个,列也是较大的那个,
--------------------------------------------------------------------------------
s1 = pd.Series([0, 1, 2, 3], index=['a', 'b', 'c', 'd'])
s2 = pd.Series([4, 5, 6], index=['c', 'd', 'e'])
ser = pd.concat([s1, s2], keys=['one', 'two'])
frame = ser.unstack() # 把 series 变成 frame
--------------------------------------------------------------------------------
frame 输出:
a b c d e
one 0.0 1.0 2.0 3.0 NaN
two NaN NaN 4.0 5.0 6.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame.stack(dropna=False) # 空数据不删除
one a 0.0
b 1.0
c 2.0
d 3.0
e NaN
two a NaN
b NaN
c 4.0
d 5.0
e 6.0
dtype: float64
frame = ser.unstack(level=0) # 按一级索引进行拆解
================================================================================
一般正常的json数据:
{'st001': {'name': 'zs', 'age': 10, 'addr': 'sh', 'mark': 's11'},
'st002': {'name': 'l1', 'age': 6, 'addr': 'bj', 'mark': 's12'},
'st003': {'name': 'wu', 'age': 8, 'addr': 'tj', 'mark': 's13'},
'st004': {'name': 'zl', 'age': 15, 'addr': 'cq', 'mark': 's14'},
'st005': {'name': 'zq', 'age': 16, 'addr': 'sh', 'mark': 's15'}}
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
frame = pd.DataFrame(stu) 加载:
输出:
st001 st002 st003 st004 st005
name zs l1 wu zl zq
age 10 6 8 15 16
addr sh bj tj cq sh
mark s11 s12 s13 s14 s15
--------------------------------------------------------------------------------
这种格式使json的原格式,容易看,但是不好分析,转置一下:
ser = frame.stack() # 原来的 索引不变,出现二级索引
输出:
name st001 zs
st002 l1
st003 wu
st004 zl
st005 zq
age st001 10
st002 6
st003 8
st004 15
st005 16
addr st001 sh
st002 bj
st003 tj
st004 cq
st005 sh
mark st001 s11
st002 s12
st003 s13
st004 s14
st005 s15
dtype: object
frame = ser.unstack(level = 0) # 使用一级索引变成 DF
frame 输出:
name age addr mark
st001 zs 10 sh s11
st002 l1 6 bj s12
st003 wu 8 tj s13
st004 zl 15 cq s14
st005 zq 16 sh s15
现在的索引是 学生编号,让他重新获取编号
frame = frame.reset_index()
frame输出:
index name age addr mark
0 st001 zs 10 sh s11
1 st002 l1 6 bj s12
2 st003 wu 8 tj s13
3 st004 zl 15 cq s14
4 st005 zq 16 sh s15
index 列名改成 stu_no:
frame.rename(columns={'index':'stu_no'}, inplace=True)
================================================================================
df = pd.DataFrame({
'name': ['s1', 's2', 's3'],
'sx': [1, 2, 3],
'yw': [4, 5, 6],
'yy': [7, 8, 9]})
输出:假设这个是三位同学的,数学,语文,英语的成绩
name sx yw yy
0 s1 1 4 7
1 s2 2 5 8
2 s3 3 6 9
数据是这样的话,是利于数据分析的,但是如果数据是保存在数据库,数据库的表是这样的
数据库表结构如下: 利于数据库存储,不利于分析,三门课程的分数都在一列上,怎么分析
name clasz score
s1 sx 1
s1 yy 2
s1 yw 3
s2 .........
把df这种利于分析的变成数据库这个格式
# pd.melt 第二个参数 id_vars 标明身份的列, 使用学生姓名的列,一维一行就是一个学生,
df_db = pd.melt(df, 'name')
df_db 输出:
name variable value
0 s1 sx 1
1 s2 sx 2
2 s3 sx 3
3 s1 yw 4
4 s2 yw 5
5 s3 yw 6
6 s1 yy 7
7 s2 yy 8
8 s3 yy 9
那么如果再把 df_db 变成之前的 df 那样的便于分析的数据呢
# df_db.pivot(index=None, columns=None, values=None) 三个参数依次:变换后的所有列, 列的名称, 列的值
df_w = df_db.pivot('name', 'variable', 'value')
df_w 输出:
variable sx yw yy
name
s1 1 4 7
s2 2 5 8
s3 3 6 9
df_w.reset_index() # 重新计算 索引
输出: 最终又变回来了
variable name sx yw yy
0 s1 1 4 7
1 s2 2 5 8
2 s3 3 6 9
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
分享
收藏
点赞人
举报
文章标签
评论列表