python数据规整化基础

这部分的数据规整化主要包括合并、重塑以及转化,其中的转换又包括清理。

合并数据集

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

默认键连接

数据集的merge和join运算是通过一个或多个键将行链接起来的。如果熟悉数据库,我们知道连接分为左连接、右连接、内连接、外连接。

首先是内连接和外连接,merge默认情况下是内连接,也可以用inner关键字来指定,内连接就是找两个数组的交集;外连接的关键字是outer,是找两个数组的并集。

df1 = pd.DataFrame({'key':['b','b','a','c','a','a','b'],'data1':range(7)})
df2 = pd.DataFrame({'key':['a','b','d'],'data2':range(3)})
print(df1)
print(df2)
print(pd.merge(df1,df2))
print(pd.merge(df1,df2,how='inner'))  #内连接
print(pd.merge(df1,df2,how='outer'))  #外连接

# key  data1
# 0   b      0
# 1   b      1
# 2   a      2
# 3   c      3
# 4   a      4
# 5   a      5
# 6   b      6
#   key  data2
# 0   a      0
# 1   b      1
# 2   d      2
#   key  data1  data2
# 0   b      0      1
# 1   b      1      1
# 2   b      6      1
# 3   a      2      0
# 4   a      4      0
# 5   a      5      0
#   key  data1  data2
# 0   b      0      1
# 1   b      1      1
# 2   b      6      1
# 3   a      2      0
# 4   a      4      0
# 5   a      5      0
#   key  data1  data2
# 0   b    0.0    1.0
# 1   b    1.0    1.0
# 2   b    6.0    1.0
# 3   a    2.0    0.0
# 4   a    4.0    0.0
# 5   a    5.0    0.0
# 6   c    3.0    NaN
# 7   d    NaN    2.0

左连接就是在右边找到左边有的值,组成新的数组;如下例所示,在左连接中,df1的键有a、b、c三个,在df2中有a、b、d,因为d在df1中没有,所以最后的左连接就不会有d,只会将df2的a、b连接起来。右连接同理。

df1 = pd.DataFrame({'key':['b','b','a','c','a','a','b'],'data1':range(7)})
df2 = pd.DataFrame({'key':['a','b','d'],'data2':range(3)})
print(df1)
print(df2)
print(pd.merge(df1,df2,how='left'))
print(pd.merge(df1,df2,how='right'))

# key  data1
# 0   b      0
# 1   b      1
# 2   a      2
# 3   c      3
# 4   a      4
# 5   a      5
# 6   b      6
#   key  data2
# 0   a      0
# 1   b      1
# 2   d      2
#   key  data1  data2
# 0   b      0    1.0
# 1   b      1    1.0
# 2   a      2    0.0
# 3   c      3    NaN
# 4   a      4    0.0
# 5   a      5    0.0
# 6   b      6    1.0
#   key  data1  data2
# 0   b    0.0      1
# 1   b    1.0      1
# 2   b    6.0      1
# 3   a    2.0      0
# 4   a    4.0      0
# 5   a    5.0      0
# 6   d    NaN      2

merge的参数如下图所示。

索引连接

上面的连接是键的连接,有的时候,我们连接键是在索引中。这个时候又是怎么样的呢?对于merge的连接方式,我们通过传入left_index=True或right_index=True来实现以索引连接。

left1 = pd.DataFrame({'key':['a','b','a','a','b','c'],'value':range(6)})
right1 = pd.DataFrame({'group_val':[3.5,7]},index=['a','b'])
print(left1)
print(right1)
print(pd.merge(left1,right1,left_on='key',right_index=True,how='outer'))

#   key  value
# 0   a      0
# 1   b      1
# 2   a      2
# 3   a      3
# 4   b      4
# 5   c      5
#    group_val
# a        3.5
# b        7.0
#   key  value  group_val
# 0   a      0        3.5
# 2   a      2        3.5
# 3   a      3        3.5
# 1   b      1        7.0
# 4   b      4        7.0
# 5   c      5        NaN

前面我们说连接的另一种方法是join实例方法,它能更方便的实现按索引合并。它还能用于合并多个带有相同或相似索引的DataFrame对象,而不管它们之间有没有重叠的列。

注意,join默认的是左连接。

left1 = pd.DataFrame({'key':['a','b','a','a','b','c'],'value':range(6)})
right1 = pd.DataFrame({'group_val':[3.5,7]},index=['0','1'])
print(left1)
print(right1)
print(left1.join(right1))

#   key  value
# 0   a      0
# 1   b      1
# 2   a      2
# 3   a      3
# 4   b      4
# 5   c      5
#    group_val
# 0        3.5
# 1        7.0
#   key  value  group_val
# 0   a      0        NaN
# 1   b      1        NaN
# 2   a      2        NaN
# 3   a      3        NaN
# 4   b      4        NaN
# 5   c      5        NaN

轴上连接

我们还有可以指定沿着轴来连接的函数,对于NumPy,我们使用concatenate函数;对于Pandas,我们使用concat函数。

arr = np.arange(9).reshape((3,3))
print(arr)
print(np.concatenate([arr,arr],axis=1))

df = pd.DataFrame(arr)
print(pd.concat([df,df],axis=0))

# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]
# [[0 1 2 0 1 2]
#  [3 4 5 3 4 5]
#  [6 7 8 6 7 8]]
#    0  1  2
# 0  0  1  2
# 1  3  4  5
# 2  6  7  8
# 0  0  1  2
# 1  3  4  5
# 2  6  7  8

concat函数的参数

合并重叠数据

我们用一种方法来实现数据的填充与替代。可以看到在df1中,如果df1是NaN,而df2中存在数字,就会用df2中的数据来填补。

import numpy as np
import pandas as pd

df1 = pd.DataFrame({'a':[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]})
print(df1)
print(df2)
print(df1.combine_first(df2))

#      a    b   c
# 0  1.0  NaN   2
# 1  NaN  2.0   6
# 2  5.0  NaN  10
# 3  NaN  6.0  14
#      a    b
# 0  5.0  NaN
# 1  4.0  3.0
# 2  NaN  4.0
# 3  3.0  6.0
# 4  7.0  8.0
#      a    b     c
# 0  1.0  NaN   2.0
# 1  4.0  2.0   6.0
# 2  5.0  4.0  10.0
# 3  3.0  6.0  14.0
# 4  7.0  8.0   NaN

重塑层次化索引

所谓重塑其实就是两个函数:stack和unstack。其中stack是将数据的列旋转成行;unstack是将数据的行旋转成列。可以看到在进行stack运算的时候,默认会滤除缺失数据。

s1 = pd.Series([0,1,2,3],index=['a','b','c','d'])
s2 = pd.Series([4,5,6],index=['c','d','e'])
data = pd.concat([s1,s2],keys=['one','two'])
print(data)
print(data.unstack())
print(data.unstack().stack())
print(data.unstack().stack(dropna=False))

# one  a    0
#      b    1
#      c    2
#      d    3
# two  c    4
#      d    5
#      e    6
# dtype: int64
#        a    b    c    d    e
# one  0.0  1.0  2.0  3.0  NaN
# two  NaN  NaN  4.0  5.0  6.0
# one  a    0.0
#      b    1.0
#      c    2.0
#      d    3.0
# two  c    4.0
#      d    5.0
#      e    6.0
# dtype: float64
# 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

数据转换

移除重复数据

import pandas as pd

data = pd.DataFrame({'k1': ['one'] * 3 + ['two'] * 4,
                     'k2': [1,1,2,3,3,4,4]})
print(data)
print(data.duplicated())  #该方法用于检测该行是否是重复数据
print(data.drop_duplicates())    #过滤重复项
print(data.drop_duplicates('k1'))  #指定要过滤的是哪一列

#     k1  k2
# 0  one   1
# 1  one   1
# 2  one   2
# 3  two   3
# 4  two   3
# 5  two   4
# 6  two   4
# 0    False
# 1     True
# 2    False
# 3    False
# 4     True
# 5    False
# 6     True
# dtype: bool
#     k1  k2
# 0  one   1
# 2  one   2
# 3  two   3
# 5  two   4
#     k1  k2
# 0  one   1
# 3  two   3

利用函数或映射进行数据转换

import pandas as pd

data = pd.DataFrame({'food':['bacon','pulled pork','bacon',
                             'Pastrami','corned beef','Bacon',
                             'pastrami','honey ham','nova lox'],
                     'ounces':[4,3,12,6,7,8,3,5,6]})
meat_to_animal = {'bacon':'pig',
                  'pulled pork':'pig',
                  'pastrami':'cow',
                  'honey ham':'pig',
                  'nova lox':'salmon'}
print(data)
data['animal'] = data['food'].map(str.lower).map(meat_to_animal)
#data['animal'] = data['food'].map(lambda x : meat_to_animal[x.lower()])
print(data)  #使用map是一种实现元素级转换以及其他数据清理工作的便捷方式。

#           food  ounces
# 0        bacon       4
# 1  pulled pork       3
# 2        bacon      12
# 3     Pastrami       6
# 4  corned beef       7
# 5        Bacon       8
# 6     pastrami       3
# 7    honey ham       5
# 8     nova lox       6
#           food  ounces  animal
# 0        bacon       4     pig
# 1  pulled pork       3     pig
# 2        bacon      12     pig
# 3     Pastrami       6     cow
# 4  corned beef       7     NaN
# 5        Bacon       8     pig
# 6     pastrami       3     cow
# 7    honey ham       5     pig
# 8     nova lox       6  salmon

替换值:利用replace函数可以实现值的替换,例如用任意值x替换NaN replace(x,NaN)。

重命名索引:利用rename来实现索引的重命名。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值