Python数据分析(五)

Python数据分析(五)

打卡第九天啦!!!

pandas库(五)

数据规整

层次化索引
  1. 层次化索引的创建
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]])
  1. 层次化索引的外层选取和内层选取
# 外层选取
data['a']
data['b':'c']
data.loc[['b','d']]

# 内层选取
data.loc[:,2]
  1. df.set_index() 使用现有列设置单(复合)索引,df.reset_index()还原索引
frame = pd.DataFrame({'a':range(7),'b':range(7,0,-1),
                     'c':['one','one','one','two','two','two','two'],
                     'd':[0,1,2,0,1,2,3]})
frame2 = frame.set_index(['c','d'])
frame2.reset_index()
数据连接
  1. pd.merge可以根据单个或多个键将不同的DataFrame的行连接起来,类似数据库的连接操作
  2. pd.merge:(left, right, how=‘inner’,on=None,left_on=None, right_on=None )
    left:合并时左边的DataFrame
    right:合并时右边的DataFrame
    how:合并的方式,默认’inner’, ‘outer’, ‘left’, ‘right’
    on:需要合并的列名,必须两边都有的列名,并以 left 和 right 中的列名的交集作为连接键
    left_on: left Dataframe中用作连接键的列
    right_on: right Dataframe中用作连接键的列
  3. 内连接 inner:对两张表都有的键的交集进行联合
    全连接 outer:对两者表的都有的键的并集进行联合
    左连接 left:对所有左表的键进行联合
    右连接 right:对所有右表的键进行联合
import pandas as pd
import numpy as np

left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                      'A': ['A0', 'A1', 'A2', 'A3'],
                       'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})

pd.merge(left,right,on='key') #指定连接键key

key    A    B    C    D
0    K0    A0    B0    C0    D0
1    K1    A1    B1    C1    D1
2    K2    A2    B2    C2    D2
3    K3    A3    B3    C3    D3
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                    'key2': ['K0', 'K1', 'K0', 'K1'],
                    'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                      'key2': ['K0', 'K0', 'K0', 'K0'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})

pd.merge(left,right,on=['key1','key2']) #指定多个键,进行合并

    key1    key2    A    B    C    D
0    K0    K0    A0    B0    C0    D0
1    K1    K0    A2    B2    C1    D1
2    K1    K0    A2    B2    C2    D2
#指定左连接

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                    'key2': ['K0', 'K1', 'K0', 'K1'],
                    'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                      'key2': ['K0', 'K0', 'K0', 'K0'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})

pd.merge(left, right, how='left', on=['key1', 'key2'])

    key1    key2          A    B    C    D
0    K0        K0        A0    B0    C0    D0
1    K0        K1        A1    B1    NaN    NaN
2    K1        K0        A2    B2    C1    D1
3    K1        K0        A2    B2    C2    D2
4    K2        K1        A3    B3    NaN    NaN
#指定右连接

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                    'key2': ['K0', 'K1', 'K0', 'K1'],
                    'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                      'key2': ['K0', 'K0', 'K0', 'K0'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})
pd.merge(left, right, how='right', on=['key1', 'key2'])

    key1    key2          A    B    C    D
0    K0        K0        A0    B0    C0    D0
1    K1        K0        A2    B2    C1    D1
2    K1        K0        A2    B2    C2    D2
3    K2        K0        NaN    NaN    C3    D3
# 指定外连接
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                    'key2': ['K0', 'K1', 'K0', 'K1'],
                    'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                      'key2': ['K0', 'K0', 'K0', 'K0'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})
pd.merge(left,right,how='outer',on=['key1','key2'])

key1    key2    A    B    C    D
0    K0    K0    A0    B0    C0    D0
1    K0    K1    A1    B1    NaN    NaN
2    K1    K0    A2    B2    C1    D1
3    K1    K0    A2    B2    C2    D2
4    K2    K1    A3    B3    NaN    NaN
5    K2    K0    NaN    NaN    C3    D3
  1. 处理重复列名:参数suffixes:默认为_x, _y
# 处理重复列名
df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                        'data' : np.random.randint(0,10,7)})
df_obj2 = pd.DataFrame({'key': ['a', 'b', 'd'],
                        'data' : np.random.randint(0,10,3)})

print(pd.merge(df_obj1, df_obj2, on='key', suffixes=('_left', '_right')))

   data_left key  data_right
0          9   b           1
1          5   b           1
2          1   b           1
3          2   a           8
4          2   a           8
5          5   a           8

# 若不指定suffixes的默认情况
  key  data_x  data_y
0   b       4       8
1   b       1       8
2   b       3       8
3   a       0       0
4   a       2       0
5   a       0       0
  1. 按索引连接:参数left_index=True或right_index=True
# 按索引连接
df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                        'data1' : np.random.randint(0,10,7)})
df_obj2 = pd.DataFrame({'data2' : np.random.randint(0,10,3)}, index=['a', 'b', 'd'])

print(pd.merge(df_obj1, df_obj2, left_on='key', right_index=True))

   data1 key  data2
0      3   b      6
1      4   b      6
6      8   b      6
2      6   a      0
4      3   a      0
5      0   a      0
数据合并
  1. 使用join方法对dataframe进行合并,能够起到和merge方法一样的效果,需要注意的是,使用join时要求没有重叠的列
left2 = pd.DataFrame([[1.,2.],[3.,4.],[5.,6.]],
                    index=['a','c','e'],
                    columns=['语文','数学'])

right2 = pd.DataFrame([[7.,8.],[9.,10.],[11.,12.],[13,14]],
                    index=['b','c','d','e'],
                    columns=['英语','综合'])

# pd.merge(left2,right2,how='outer',left_index=True,right_index=True)
left2.join(right2,how='outer')

    语文   数学    英语    综合
a   1.0    2.0     NaN     NaN
b   NaN    NaN     7.0     8.0
c   3.0    4.0     9.0     10.0
d   NaN    NaN     11.0    12.0
e   5.0    6.0     13.0    14.0
  1. 使用concat方法沿轴方向将多个对象合并到一起
    (1)NumPy的concat:np.concatenate
import numpy as np
import pandas as pd

arr1 = np.random.randint(0, 10, (3, 4))
arr2 = np.random.randint(0, 10, (3, 4))

print(arr1)
print(arr2)

print(np.concatenate([arr1, arr2]))
print(np.concatenate([arr1, arr2], axis=1))

# print(arr1)
[[3 3 0 8]
 [2 0 3 1]
 [4 8 8 2]]

# print(arr2)
[[6 8 7 3]
 [1 6 8 7]
 [1 4 7 1]]

# print(np.concatenate([arr1, arr2]))
 [[3 3 0 8]
 [2 0 3 1]
 [4 8 8 2]
 [6 8 7 3]
 [1 6 8 7]
 [1 4 7 1]]

# print(np.concatenate([arr1, arr2], axis=1)) 
[[3 3 0 8 6 8 7 3]
 [2 0 3 1 1 6 8 7]
 [4 8 8 2 1 4 7 1]]

  (2)pd.concat:注意指定轴方向,默认axis=0;join指定合并方式,默认为outer;Series合并时查看行索引有无重复

df1 = pd.DataFrame(np.arange(6).reshape(3,2),index=list('abc'),columns=['one','two'])

df2 = pd.DataFrame(np.arange(4).reshape(2,2)+5,index=list('ac'),columns=['three','four'])

pd.concat([df1,df2]) #默认外连接,axis=0

    four    one    three    two
a    NaN        0.0    NaN        1.0
b    NaN        2.0    NaN        3.0
c    NaN        4.0    NaN        5.0
a    6.0        NaN    5.0        NaN
c    8.0        NaN    7.0        NaN

pd.concat([df1,df2],axis='columns') #指定axis=1连接

    one    two    three    four
a    0    1    5.0        6.0
b    2    3    NaN        NaN
c    4    5    7.0        8.0

#同样我们也可以指定连接的方式为inner
pd.concat([df1,df2],axis=1,join='inner')

    one    two    three    four
a    0    1    5        6
c    4    5    7        8
重塑层次化索引
  1. stack方法能够将列索引转换为行索引,完成层级索引,即将dataframe转换为series,需要注意的是,stack默认过滤缺失数据,可以修改参数dropna为False来不忽略掉其中的缺失数据
import numpy as np
import pandas as pd

df_obj = pd.DataFrame(np.random.randint(0,10, (5,2)), columns=['data1', 'data2'])
print(df_obj)

stacked = df_obj.stack()
print(stacked)

# print(df_obj)
   data1  data2
0      7      9
1      7      8
2      8      9
3      4      1
4      1      2

# print(stacked)
0  data1    7
   data2    9
1  data1    7
   data2    8
2  data1    8
   data2    9
3  data1    4
   data2    1
4  data1    1
   data2    2
dtype: int64

a1 = pd.Series(np.arange(4),index=list('abcd'))
a2 = pd.Series([4,5,6],index=list('cde'))
s1 = pd.concat([a1,a2],keys=['data1','data2'])

print(s1)
data1  a    0
       b    1
       c    2
       d    3
data2  c    4
       d    5
       e    6
dtype: int64

print(s1.unstack())
         a    b    c    d    e
data1  0.0  1.0  2.0  3.0  NaN
data2  NaN  NaN  4.0  5.0  6.0

print(s1.unstack().stack())
data1  a    0.0
       b    1.0
       c    2.0
       d    3.0
data2  c    4.0
       d    5.0
       e    6.0
dtype: float64

print(s1.unstack().stack(dropna=False))
data1  a    0.0
       b    1.0
       c    2.0
       d    3.0
       e    NaN
data2  a    NaN
       b    NaN
       c    4.0
       d    5.0
       e    6.0
dtype: float64
  1. unstack方法能够将层级索引展开,即将series转换为dataframe,默认操作的是内层索引,可以通过修改level参数操作外层索引
# 默认操作内层索引
print(stacked.unstack())

# 通过level指定操作索引的级别
print(stacked.unstack(level=0))

# print(stacked.unstack())
   data1  data2
0      7      9
1      7      8
2      8      9
3      4      1
4      1      2

# print(stacked.unstack(level=0))
       0  1  2  3  4
data1  7  7  8  4  1
data2  9  8  9  1  2
轴向旋转
  1. 使用pivot方法
  2. 等效于set_index方法和unstack方法的结合

数据分组和聚合

  1. 使用groupby方法对数据进行分组
df1 = pd.DataFrame({'fruit':['apple','banana','orange','apple','banana'],
                    'color':['red','yellow','yellow','cyan','cyan'],
                   'price':[8.5,6.8,5.6,7.8,6.4]})
#查看类型
type(df1.groupby('fruit'))
# pandas.core.groupby.groupby.DataFrameGroupBy  #GruopBy对象,它是一个包含组名,和数据块的2维元组序列,支持迭代
for name,group in g:
    print(name)
    print('-'*50)
    print(group)
    print('-'*50)

apple
--------------------------------------------------
   fruit color  price
0  apple   red    8.5
3  apple  cyan    7.8
--------------------------------------------------
banana
--------------------------------------------------
    fruit   color  price
1  banana  yellow    6.8
4  banana    cyan    6.4
--------------------------------------------------
orange
--------------------------------------------------
    fruit   color  price
2  orange  yellow    5.6
--------------------------------------------------

#选择任意的数据块
dict(list(df1.groupby('fruit')))['apple']  #取出apple组的数据块,数据块是dataframe类型
   fruit color  price
0  apple   red    8.5
3  apple  cyan    7.8
  1. 聚合
#根据fruit来求price的平均值
df1['price'].groupby(df1['fruit']).mean()
fruit
apple     8.15
banana    6.60
orange    5.60
Name: price, dtype: float64     
#或者
# df1.groupby('fruit')['price'].mean()

#as_index=False 对生成的结果添加索引
df1.groupby('fruit',as_index=False)['price'].mean()
    fruit    price
0    apple    8.15
1    banana    6.60
2    orange    5.60

# 计算每种水果的差值
#定义一个计算差值的函数
def diff_value(arr):
    return arr.max() - arr.min()
#使用自定义聚合函数,我们需要将函数传递给agg或aggregate方法,我们使用自定义聚合函数时,会比我们表中的聚合函数慢的多,因为要进行函数调用,数据重新排列
df1.groupby('fruit')['price'].agg(diff_value)
fruit
apple     0.7
banana    0.4
orange    0.0
Name: price, dtype: float64
  1. 根据字典进行分组
people = pd.DataFrame(np.random.randn(5,5),
                     columns=['a','b','c','d','e'],
                     index=['Sam','Mark','Tony','Jim','Nana'])
m = {'a':'red','b':'red','c':'blue','d':'blue','e':'red'}
people.groupby(m,axis=1).sum()
  1. 根据Series进行分组
s1 = pd.Series(m)
people.groupby(s1,axis=1).count()
  1. 根据函数进行分组
             a         b         c         d         e
Sam  -0.279162 -0.931083 -1.458116  0.804832 -2.221332
Mark  1.821431  0.229115 -0.189306 -1.031984  0.819726
Tony -1.719586  2.527962 -1.297797 -1.645674  1.497407
Jim   0.901139  2.175730  0.270985  0.810589  0.246046
Nana  1.098260  2.104255  0.847701 -0.536705  0.807047

people.groupby(len).sum()

          a         b         c         d         e
3  0.621977  1.244646 -1.187130  1.615422 -1.975286
4  1.200105  4.861332 -0.639402 -3.214363  3.124180
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值