数据分析

数据分析 第二章

数据分析 第二节 数据重构

数据的合并

层次化索引能以低维度形式处理高维度数据。
层次化索引在数据重塑和基于分组的操作(如透明表生成)中扮演着重要的角色。
例子:可以通过unstack方法将这段数据重新安排到一个DataFrame中:

In [9]: data = pd.Series(np.random.randn(9)),index=[['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'], [1, 2, 3, 1, 3, 1, 2, 2, 3]]
In [10]; data
Out[10]:
a  1   -0.204708
   2    0.478943
   3   -0.519439
b  1   -0.555730
   3    1.965781
c  1    1.393406
   2    0.092908
d  2    0.281746
   3    0.769023
dtype: float64   

In [16]: data.unstack()
Out[16]:
          1         2          3
a -0.204708  0.478943  -0.519439
b -0.555730       NaN   1.965781
c  1.393406  0.092908        NaN
d       NaN  0.281746   0.769023

unstack的逆运算是stack:

In [17]: data.unstack().stack()

合并数据集

pandas对象中的数据可以通过一些方式进行合并:
1、pandas.merge可根据一个或多个键将不同DataFrame的行连接起来。
2、pandas.concat可以沿着一条轴将多个对象堆叠到一起。
3、实例方法combine_first可以将重复数据编接在一起,用一个对象中的值填充另一个对象中的缺失值。

数据集的合并(merge)或连接(join)运算是通过一个或多个键将行连接起来的。

merge函数

In [35]: df1 = pd.DataFrame({'Key':['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7)})

In [36]: df2 = pd.DataFrame({'key': ['a', 'b', 'd'], 'data2': range(3)})

In [37]:df1
out[37];
     data1   key
0        0     b
1        1     b
2        2     a
3        3     c
4        4     a
5        5     a
6        6     b

In [38]: df2
Out[38]:
   data2   key
0      0     a
1      1     b
2      2     d

#多对一的合并。df1中的数据有多个被标记为a和b的行,而df2中key列的每个值仅对一行。(使用key连接到一起,有相对应的key,则横向连接到一起)
#对这些对象调用merge即可得:

In [39]: pd.merge(df1, df2)
Out[39]:
     data1  key  data2
0        0    b      1
1        1    b      1
2        6    b      1
3        2    a      0
4        4    a      0
5        5    a      0  

如果没有指明要用哪个列进行连接,merge就会将重叠列的列名当做键。

#指明相应的列进行连接

In [40]: pd.merge(df1, df2, on='key')
Out[40]:
   data1  key  data2
0      0    b      1
1      1    b      1
2      6    b      1
3      2    a      0
4      4    a      0
5      5    a      0

如果两个对象的列名不同,也可以分别进行指定:
(命名的列名不同,但是对象所对应的值时相同的)

In [41]: df3 = pd.DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'data1':range(7)]})
In [42]: df4 = pd.DataFrame({'rkey': ['a', 'b', 'd'], 'data2': range(3)})
In [43]: pd.merge(df3, df4, left_on='1key', right_on='rkey')
Out[43]:
    data1  lkey  data2  rkey
0       0     b      1     b
1       1     b      1     b
2       6     b      1     b
3       2     a      0     a
4       4     a      0     a
5       5     a      0     a

# c和d以及与之相应的数据消失了。 

默认情况下,merge做的是“内连接”;结果中的键是交集。其他方式有“left”、“right”、“outer”。
内连接:结果是键的交集。
外连接:求取的是键的并集,组合了左连接和右连接的效果。

#例子:外连接,其中一个数据索引没有相对应的值就用NaN表示
In [44]: pd.merge(df1, df2, how='outer')
Out[44]:
    data1  key  data2
0     0.0    b    1.0
1     1.0    b    1.0
2     6.0    b    1.0
3     2.0    a    0.0
4     4.0    a    0.0
5     5.0    a    0.0
6     3.0    c    NaN
7     NaN    d    2.0

merge函数选项总结:

选项说明
inner使用两个表都有的键
left使用左表中所有的键
right使用右表中所有的键
outer使用两个表中所有的键

多对多连接产生的是行的笛卡尔积。例如左边的DataFrame有3个“b”行,右边的有2个,所以最终结果中就有6个“b”行。连接方式只影响出现在结果中的不同的键的值。

对于重复列名的处理,使用merge的suffixes选项,用于指定附加到左右两个DataFrame对象的重复列名上的字符串:

In [55]: pd.merge(left, right, on='key1', suffixes=('_left', '_right'))
Out[55]:
   key1  key2_left  lval  key2_right  rval
   ……
   ……

merge函数的参数

参数说明
left参与合并的左侧DataFrame
right参与合并的右侧DataFrame
how“inner”、“outer”、“left”、“right"其中之一。 默认为"inner”
on用于连接的列名。必须存在于左右两个DataFrame对象中。如未指定,则以left和right列名的交集作为连接键
left_on左侧DataFrame中用作连接键的列
right_on右侧DataFrame中用作连接键的列
left_index将左侧的行索引用作其连接键
right_index类似于left_index
sort根据连接键对合并后的数据进行排序,默认为True(升序)
suffixes字符串值元组,用于追加到重叠列名的末尾,默认为(’_x’, ‘_y’)。
copy设置为False,可以在某些特殊情况下避免将数据复制到结果数据结构中。默认总是复制

轴向连接(纵向连接)

concat函数

#假设有三个没有重复索引的Series

In [82]: s1 = pd.Series([0, 1], index=['a', 'b'])
In [83]: s2 = pd.Series([2, 3, 4], index=['c', 'd', 'e'])
In [84]: s3 = pd.Series([5, 6], index=['f', 'g'])

#对这些对向调用concat可以将值和索引粘和在一起:

In [85]: pd.concat([s1, s2, s3])
Out[85]:
a  0
b  1
c  2
d  3
e  4
f  5
g  6
dtype: int64

默认情况下,concat是在axis=0上工作的,最终产生一个新的Series。如果传入axis=1,则结果就会变成一个DataFrame(axis = 1是列):

#生成DataFrame的情况
In [86]: pd.concat([s1, s2, s3], axis=1)
Out[86]:
     0    1    2
a  0.0  NaN  NaN
b  1.0  NaN  NaN
c  NaN  2.0  NaN
d  NaN  3.0  NaN
e  NaN  4.0  NaN
f  NaN  NaN  5.0
g  NaN  NaN  6.0

使用concat函数,传入join='inner’即可得到它们的交集:

In [89]: pd.concat([s1, s4], axis=1)
Out[89]:
     0  1
a  0.0  0
b  1.0  1
f  NaN  5
g  NaN  6

In [90]: pd.concat([s1, s4], axis=1, join='inner')
Out[90]:
   0   1
a  0   0
b  1   1

可以通过join_axes指定要在其它轴上使用的索引:

In [91]: pd.concat([s1, s4], axis=1, join_axes=[['a', 'c', 'b', 'e']])
Out[91]:
     0     1
a  0.0   0.0
c  NaN   NaN
b  1.0   1.0
e  NaN   NaN

使用keys参数可以在连续轴上创建一个层次化索引。

In [92]:result = pd.concat([s1, s1, s3], keys=['one', 'two', 'three'])

In [93]: result
Out[93]:
one   a   0
      b   1
two   a   0
      b   1
three f   5
      g   6
dtype: int64
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值