pandas学习笔记四:运算方法和运算工具

1、数值计算和统计基础

import numpy as np
import pandas as pd

# 基本参数:axis、skipna

df = pd.DataFrame({'key1':[4,5,3,np.nan,2],
                 'key2':[1,2,np.nan,4,5],
                 'key3':[1,2,3,'j','k']},
                 index = ['a','b','c','d','e'])
print(df)
print(df.mean())
print(df.mean(axis=1))
# np.nan :空值
# .mean()计算均值
# 只统计数字列
# 可以通过索引单独统计一列
# axis参数:默认为0,以列来计算,axis=1,以行来计算,这里就按照行来汇总了

print(df.mean(skipna=False))

# 主要数学计算方法,可用于Series和DataFrame(1)

df = pd.DataFrame({'key1':np.arange(10),
                  'key2':np.random.rand(10)*10})
print(df)
print('-----')

print(df.count(),'→ count统计非Na值的数量\n')
print(df.min(),'→ min统计最小值\n',df['key2'].max(),'→ max统计最大值\n')
print(df.quantile(q=0.75),'→ quantile统计分位数,参数q确定位置\n')
print(df.sum(),'→ sum求和\n')
print(df.mean(),'→ mean求平均值\n')
print(df.median(),'→ median求算数中位数,50%分位数\n')
print(df.std(),'\n',df.var(),'→ std,var分别求标准差,方差\n')
print(df.skew(),'→ skew样本的偏度\n')
print(df.kurt(),'→ kurt样本的峰度\n')

print('====================================')
df = pd.DataFrame({'key1':np.arange(10),
                  'key2':np.random.rand(10)*10})
print(df)
print(df.cumsum())
print(df.cumprod())
# 如果是随机生成的小数,累计积cumprod的结果是科学计数法

print(df.cummax())
print(df.cummin())
# 会填充key1,和key2的值

s = pd.Series(list('asdvasdcfgg'))
sq = s.unique()
print(s)
print(sq,type(sq))
print(pd.Series(sq))
# 得到一个唯一值数组
# 通过pd.Series重新变成新的Series

sq.sort()
print(sq)
# 重新排序

# 值计数:.value_counts()

print(s.value_counts())
# 得到一个新的Series,计算出不同值出现的频率
# sort参数:排序,默认为True
print('===========================================')

# 成员资格:.isin()

s = pd.Series(np.arange(10,15))
df = pd.DataFrame({'key1':list('asdcbvasd'),
                  'key2':np.arange(4,13)})
print(s)
print(df)

print(s.isin([5,14]))
print(df.isin(['a','bc','10',8]))
# 用[]表示
# 得到一个布尔值的Series或者Dataframe

2、数值计算和统计基础作业

import numpy as np
import pandas as pd

# 作业1:如图创建一个Dataframe(5*2,值为0-100的随机值),并分别计算key1和key2的均值、中位数、累积和

df = pd.DataFrame(np.random.rand(5, 2) * 100, columns=['key1', 'key2'])
print(df)
print(df['key1'].mean())
print(df['key2'].mean())
print(df['key1'].median())
print(df['key2'].median())
df['key1_cumsum'] = df['key1'].cumsum()
df['key2_cumsum'] = df['key2'].cumsum()
print(df)
print('====================================================')

# 作业2:写出一个输入元素直接生成数组的代码块,然后创建一个函数,该函数功能用于判断一个Series是否是唯一值数组,返回“是”和“不是”

def is_unque_series(series):
    if series.is_unique:
        return '是'
    else:
        return '否'

str = input('请输入元素,逗号分割:\n')
print(str)
s = pd.Series(str.split(','))
print(is_unque_series(s))

3、文本数据

import numpy as np
import pandas as pd

# Pandas针对字符串配备的一套方法,使其易于对数组的每个元素进行操作

# 通过str访问,且自动排除丢失/ NA值

s = pd.Series(['s', 'df', 'ds', 'a', 's', 'a', 'dd'])
df = pd.DataFrame({'key1': list('abcdef'), 'key2': ['s', 'df', 'ds', 'a', 's', 'a']})
print(s.str.count('a'))
print(df['key2'].str.upper())
# 直接通过.str调用字符串方法
# 可以对Series、Dataframe使用
# 自动过滤NaN值

print(df.columns.str.upper())
# df.columns是一个Index对象,也可使用.str

# 字符串常用方法(1) - lower,upper,len,startswith,endswith

s = pd.Series(['A','b','bbhello','123',np.nan])

print(s.str.lower(),'→ lower小写\n')
print(s.str.upper(),'→ upper大写\n')
print(s.str.len(),'→ len字符长度\n')
print(s.str.startswith('b'),'→ 判断起始是否为a\n')
print(s.str.endswith('3'),'→ 判断结束是否为3\n')

# 字符串常用方法(2) - strip

s = pd.Series([' jack', 'jill ', ' jesse ', 'frank'])
df = pd.DataFrame(np.random.randn(3, 2), columns=[' Column A ', ' Column B '],
                  index=range(3))
print(s)
print(df)
print('-----')

print(s.str.strip().values)  # 去除字符串中的空格
print(s.str.lstrip().values)  # 去除字符串中的左空格
print(s.str.rstrip().values)  # 去除字符串中的右空格

# 字符串常用方法(3) - replace

df = pd.DataFrame(np.random.randn(3, 2), columns=[' Column A ', ' Column B '],
                  index=range(3))
df.columns = df.columns.str.replace(' ','-')
print(df)
# 替换

df.columns = df.columns.str.replace('-','hehe',n=1)
print(df)
# n:替换个数

# 字符串常用方法(4) - split、rsplit

s = pd.Series(['a,b,c','1,2,3',['a,,,c'],np.nan])
print(s.str.split(','))
print('-----')
# 类似字符串的split

print(s.str.split(',')[0])
print('-----')
# 直接索引得到一个list

print(s.str.split(',').str[0])
print(s.str.split(',').str.get(1))
print('-----')
# 可以使用get或[]符号访问拆分列表中的元素

print(s.str.split(',', expand=True))
print(s.str.split(',', expand=True, n = 1))
print(s.str.rsplit(',', expand=True, n = 1))
print('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
# 可以使用expand可以轻松扩展此操作以返回DataFrame
# n参数限制分割数
# rsplit类似于split,反向工作,即从字符串的末尾到字符串的开头

df = pd.DataFrame({'key1':['a,b,c','1,2,3',[':,., ']],
                  'key2':['a-b-c','1-2-3',[':-.- ']]})
print(df['key2'].str.split('-'))
print('======================================')
# Dataframe使用split

# 字符串索引

s = pd.Series(['A','b','C','bbhello','123',np.nan,'hj'])
df = pd.DataFrame({'key1':list('abcdef'),
                  'key2':['hee','fv','w','hija','123',np.nan]})

print(s.str[0])  # 取第一个字符串
print(s.str[:2])  # 取前两个字符串
print(df['key2'].str[0])
# str之后和字符串本身索引方式相同

4、文本数据作业

import numpy as np
import pandas as pd

# 作业1:如图创建一个Dataframe,并分别通过字符串常用方法得到3个Series或得到新的Dataframe:
# ① name字段首字母全部大写
# ② gender字段去除所有空格
# ③ score字段按照-拆分,分别是math,english,art三个学分

df = pd.DataFrame({'gender':[' M', 'M ', ' F ', 'M', 'F '],
                   'name':['Jack', 'tom', 'marry', 'zack', 'Heheda'],
                   'score':['90-92-89','89-78-88','90-92-95','78-88-76','60-60-67']})
df['name'] = df['name'].str.capitalize()
df['gender'] = df['gender'].str.strip()
print(df['name'])
print(df['gender'].values)
df['math'] = df['score'].str.split('-', expand=True)[0]
# 也可以指定扩展出第一个元素
# df['math'] = df['score'].str.split('-', expand=True, n = 1)[0]
df['english'] = df['score'].str.split('-', expand=True)[1]
df['art'] = df['score'].str.split('-', expand=True)[2]
print(df)

5、合并

import numpy as np
import pandas as pd

# Pandas具有全功能的,高性能内存中连接操作,与SQL等关系数据库非常相似

# pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
#          left_index=False, right_index=False, sort=True,
#          suffixes=('_x', '_y'), copy=True, indicator=False)

df1 = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                     'A': ['A0', 'A1', 'A2', 'A3'],
                     'B': ['B0', 'B1', 'B2', 'B3']})
df2 = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})
df3 = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                    'key2': ['K0', 'K1', 'K0', 'K1'],
                    'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3']})
df4 = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                    'key2': ['K0', 'K0', 'K0', 'K0'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']})
print(df1)
print(df2)
print(pd.merge(df1, df2, on='key'))
print('============================================')
# left:第一个df
# right:第二个df
# on:参考键
print(df3)
print(df4)
print(pd.merge(df3, df4, on=['key1', 'key2']))
print('============================================')
# 多个链接键

# 参数how → 合并方式

print(pd.merge(df3, df4, on=['key1', 'key2'], how='inner'))
print(pd.merge(df3, df4, on=['key1', 'key2'], how='outer'))
print(pd.merge(df3, df4, on=['key1', 'key2'], how='left'))
print(pd.merge(df3, df4, on=['key1', 'key2'], how='right'))
print('----------------------------------------------------')
# inner:默认,取交集
# outer:取并集,数据缺失范围NaN
# left:按照df3为参考合并,数据缺失范围NaN
# right:按照df4为参考合并,数据缺失范围NaN

# 参数 left_on, right_on, left_index, right_index → 当键不为一个列时,可以单独设置左键与右键

df1 = pd.DataFrame({'lkey':list('bbacaab'),
                   'data1':range(7)})
df2 = pd.DataFrame({'rkey':list('abd'),
                   'date2':range(3)})
print(pd.merge(df1, df2, left_on='lkey', right_on='rkey'))
# df1以‘lkey’为键,df2以‘rkey’为键

df2 = pd.DataFrame(range(3), index=list('abd'))
print(pd.merge(df1, df2, left_on='lkey', right_index=True))
# df1以‘key’为键,df2以index为键
# left_index:为True时,第一个df以index为键,默认False
# right_index:为True时,第二个df以index为键,默认False

# 所以left_on, right_on, left_index, right_index可以相互组合:
# left_on + right_on, left_on + right_index, left_index + right_on, left_index + right_index


# 参数 sort

df1 = pd.DataFrame({'key':list('bbacaab'),
                   'data1':[1,3,2,4,5,9,7]})
df2 = pd.DataFrame({'key':list('abd'),
                   'date2':[11,2,33]})
r1= pd.merge(df1, df2, on='key', how='outer')
print(r1)
print(pd.merge(df1, df2, on='key', sort=True, how='outer'))
print('----------------------------------------------')
# sort:按照字典顺序通过 连接键 对结果DataFrame进行排序。默认为False,设置为False会大幅提高性能

print(r1.sort_values('data1'))
# 也可直接用Dataframe的排序方法:sort_values,sort_index

# pd.join() → 直接通过索引链接

left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                     'B': ['B0', 'B1', 'B2']},
                    index=['K0', 'K1', 'K2'])
right = pd.DataFrame({'C': ['C0', 'C2', 'C3'],
                      'D': ['D0', 'D2', 'D3']},
                     index=['K0', 'K2', 'K3'])
print(left)
print(right)
print(left.join(right))
print(left.join(right, how='outer'))
print('-----')
# 等价于:pd.merge(left, right, left_index=True, right_index=True, how='outer')

df1 = pd.DataFrame({'key':list('bbacaab'),
                   'data':[1,3,2,4,5,9,7]})
df2 = pd.DataFrame({'key':list('abd'),
                   'data':[11,2,33]})
print(df1)
print(df2)
print(pd.merge(df1, df2, left_index=True, right_index=True, suffixes=('_1', '_2')))
print('-----')
# suffixes=('_x', '_y'),当连接的结果中有相同字段时添加后缀,方便区分字段

left = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                     'B': ['B0', 'B1', 'B2', 'B3'],
                     'key': ['K0', 'K1', 'K0', 'K1']})
right = pd.DataFrame({'C': ['C0', 'C1'],
                      'D': ['D0', 'D1']},
                     index=['K0', 'K1'])
print(left)
print(right)
print(left.join(right, on = 'key'))
# 等价于pd.merge(left, right, left_on='key', right_index=True, how='left', sort=False);
# left的‘key’和right的index

6、合并作业

import numpy as np
import pandas as pd

# 作业1:按要求创建Dataframe df1、df2,并合并成df3
df1 = pd.DataFrame({'key':list('abc'),
                    'value1':np.random.rand(3)})
df2 = pd.DataFrame({'key':list('bcd'),
                    'value2':np.random.rand(3)})
print(pd.merge(df1, df2, on='key', how='outer'))

# 作业2:按要求创建Dataframe df1、df2,并合并成df3
df1 = pd.DataFrame({'lkey':list('abc'),
                    'value1':np.random.rand(3)})
df2 = pd.DataFrame({'rkey':list('bcd'),
                    'value2':np.random.rand(3)})
print(pd.merge(df1, df2, left_on='lkey', right_on='rkey', how='left'))

# 作业3:按要求创建Dataframe df1、df2,并合并成df3
print(np.arange(5,8))
df1 = pd.DataFrame({'key':list('abc'),
                    'value1':np.random.rand(3)})
df2 = pd.DataFrame({'value1':np.random.rand(3),
                    'value2':np.arange(5,8)}, index=list('bcd'))
print(df2)
print(pd.merge(df1, df2, left_on='key', right_index=True, how='inner'))

7、 连接与修补

import numpy as np
import pandas as pd

# 连接与修补 concat、combine_first
#
# 连接 - 沿轴执行连接操作
#
# pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
#           keys=None, levels=None, names=None, verify_integrity=False,
#           copy=True)

# 连接:concat

s1 = pd.Series([1,2,3])
s2 = pd.Series([2,3,4])
s3 = pd.Series([1,2,3],index = ['a','c','h'])
s4 = pd.Series([2,3,4],index = ['b','e','d'])
print(pd.concat([s1,s2]))
print(pd.concat([s3,s4]).sort_index())
print('-----')
# 默认axis=0,行+行

print(pd.concat([s3,s4], axis=1))
print('-----')
# axis=1,列+列,成为一个Dataframe

# 连接方式:join,join_axes

s5 = pd.Series([1,2,3],index = ['a','b','c'])
s6 = pd.Series([2,3,4],index = ['b','c','d'])
print(pd.concat([s5,s6], axis= 1))
print(pd.concat([s5,s6], axis= 1, join='inner'))
# join:{'inner','outer'},默认为“outer”。如何处理其他轴上的索引。outer为联合和inner为交集。
# print(pd.concat([s5,s6], axis= 1, join_axes=[['a','b','d']]))
# join_axes:在0.25版中已弃用

# 层次索引

sre = pd.concat([s5,s6], keys = ['one','two'])
print(sre,type(sre))
print('-----')
# keys:序列,默认值无。使用传递的键作为最外层构建层次索引

sre = pd.concat([s5,s6], axis=1, keys = ['one','two'])
print(sre,type(sre))
print('=========================================')
# axis = 1, 覆盖列名

# 修补 pd.combine_first()

df1 = pd.DataFrame([[np.nan, 3., 5.], [-4.6, np.nan, np.nan],[np.nan, 7., np.nan]])
df2 = pd.DataFrame([[-42.6, np.nan, -8.2], [-5., 1.6, 4]],index=[1, 3])
print(df1)
print(df2)
print(df1.combine_first(df2))
print('-----')
# 根据index,df1的空值被df2替代
# 如果df2的index多于df1,则更新到df1上,比如index=['a',1]

df1.update(df2)
print(df1)
# update,直接df2覆盖df1,相同index位置

8、 连接与修补作业

import numpy as np
import pandas as pd

# 作业1:按要求创建Dataframe df1、df2,并连接成df3
df1 = pd.DataFrame(np.random.rand(4,2), index=list('abcd'), columns=['values1', 'values2'])
df2 = pd.DataFrame(np.random.rand(4,2), index=list('efgh'), columns=['values1', 'values2'])
print(df1)
print(df2)
print(pd.concat([df1, df2]))

# 作业2:按要求创建Dataframe df1、df2,并用df2的值修补df1,生成df3
df1 = pd.DataFrame(np.random.rand(4,2), index=list('abcd'), columns=['values1', 'values2'])
df1.loc['b']['values1'] = np.NaN
df1.loc['c']['values1'] = np.NaN
print(df1)
print(np.arange(0, 8, step=2))
df2 = pd.DataFrame({'values1': np.arange(0, 8, step=2),
                    'values2': np.arange(1, 9, step=2)},
                   index=list('abcd'))
print(df2)
print(df1.combine_first(df2))

9、去重及替换

import numpy as np
import pandas as pd

# .duplicated / .replace

# 去重 .duplicated

s = pd.Series([1,1,1,1,2,2,2,3,4,5,5,5,5])
print(s.duplicated())
print(s[s.duplicated() == False])
print('-----')
# 判断是否重复
# 通过布尔判断,得到不重复的值

print(s.drop_duplicates())
# drop.duplicates移除重复
# inplace参数:是否替换原值,默认False

df = pd.DataFrame({'key1':['a','a',3,4,5],
                  'key2':['a','a','b','b','c']})
print(df)
print(df.duplicated())
print(df.drop_duplicates())
# Dataframe中使用duplicated

# 替换 .replace

s = pd.Series(list('ascaazsd'))
print(s.replace('a', 'two'))
print(s.replace(['a', 'c'], 'three'))
print(s.replace({'a': 'one', 'c': 'two'}))
# 可一次性替换一个值或多个值
# 可传入列表或字典

10、数据分组

import numpy as np
import pandas as pd

# 分组统计 - groupby功能
#
# ① 根据某些条件将数据拆分成组
# ② 对每个组独立应用函数
# ③ 将结果合并到一个数据结构中
#
# Dataframe在行(axis=0)或列(axis=1)上进行分组,将一个函数应用到各个分组并产生一个新值,然后函数执行结果被合并到最终的结果对象中。
#
# df.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, **kwargs)

df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar','foo', 'bar', 'foo', 'foo'],
                   'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
                   'C' : np.random.randn(8),
                   'D' : np.random.randn(8)})
print(df)
print(df.groupby('A'), type(df.groupby('A')))
# 直接分组得到一个groupby对象,是一个中间数据,没有进行计算

a = df.groupby('A').mean()
print(a, type(a))
b = df.groupby(['A', 'B']).mean()
print(b)
c = df.groupby('A')['D'].mean()  # 以A分组,算D的平均值
print(c)
# 通过分组后的计算,得到一个新的dataframe
# 默认axis = 0,以行来分组
# 可单个或多个([])列分组


# 分组 - 可迭代对象
df = pd.DataFrame({'X' : ['A', 'B', 'A', 'B'], 'Y' : [1, 4, 3, 2]})
for n,g in df.groupby('X'):
    print(n)
    print(g)
    print('----------')
# n是组名,g是分组后的Dataframe

print(df.groupby('X').get_group('A'))
print('+++++++++++')
# .get_group()提取分组后的组

print(df.groupby('X').groups) # 分组后字典的值是dataframe的索引
print(df.groupby('X').groups['A'])
# .groups:将分组后的groups转为dict
# 可以字典索引方法来查看groups里的元素

print(df.groupby('X').size())
print('==================================')
# .size():查看分组后的长度

# 其他轴上的分组

df = pd.DataFrame({'data1':np.random.rand(2),
                  'data2':np.random.rand(2),
                  'key1':['a','b'],
                  'key2':['one','two']})
for n,g in df.groupby(df.dtypes, axis=1):
    print(n)
    print(g)
# 按照值类型分列
print('============================')

# 通过字典或者Series分组

df = pd.DataFrame(np.arange(16).reshape(4,4),
                  columns = ['a','b','c','d'])
mapping = {'a':'one','b':'one','c':'two','d':'two','e':'three'}
print(df.groupby(mapping, axis=1).sum())
# mapping中,a、b列对应的为one,c、d列对应的为two,以字典来分组

print('----------------------')
s = pd.Series(mapping)
print(s,'\n')
print(s.groupby(s).count())
# s中,index中a、b对应的为one,c、d对应的为two,以Series来分组

# 通过函数分组

df = pd.DataFrame(np.arange(16).reshape(4,4),
                  columns = ['a','b','c','d'],
                 index = ['abc','bcd','aa','b'])
print(df.groupby(len).groups)
print(df.groupby(len).sum())
print(df.groupby(len).count())
print('====================================')

# 按照字母长度分组

# 分组计算函数方法

s = pd.Series([1, 2, 3, 10, 20, 30], index = [1, 2, 3, 1, 2, 3])
grouped = s.groupby(level=0)  # 唯一索引用.groupby(level=0),将同一个index的分为一组
print(grouped)
print(grouped.first(),'→ first:非NaN的第一个值\n')
print(grouped.last(),'→ last:非NaN的最后一个值\n')
print(grouped.sum(),'→ sum:非NaN的和\n')
print(grouped.mean(),'→ mean:非NaN的平均值\n')
print(grouped.median(),'→ median:非NaN的算术中位数\n')
print(grouped.count(),'→ count:非NaN的值\n')
print(grouped.min(),'→ min、max:非NaN的最小值、最大值\n')
print(grouped.std(),'→ std,var:非NaN的标准差和方差\n')
print(grouped.prod(),'→ prod:非NaN的积\n')
print('---------------------------------------------------------')

# 多函数计算:agg()

df = pd.DataFrame({'a':[1,1,2,2],
                  'b':np.random.rand(4),
                  'c':np.random.rand(4),
                  'd':np.random.rand(4),})
print(df)
print(df.groupby('a').agg(['mean', np.sum]))
# print(df.groupby('a')['b'].agg({'mean1': np.mean,
#                                 'sum1': np.sum}))
# 报错:pandas.core.base.SpecificationError: nested renamer is not supported
# pandas 1.0版本以后写法:
print(df.groupby('a')['b'].agg([('mean1', np.mean), ('sum1', np.sum)]))

11、数据分组作业

import numpy as np
import pandas as pd

# 作业1:按要求创建Dataframe df,并通过分组得到以下结果
# ① 以A分组,求出C,D的分组平均值
# ② 以A,B分组,求出D,E的分组求和
# ③ 以A分组,得到所有分组,以字典显示
# ④ 按照数值类型分组,求和
# ⑤ 将C,D作为一组分出来,并计算求和
# ⑥ 以B分组,求出每组的均值,求和,最大值,最小值

df = pd.DataFrame({'A' : ['one', 'two', 'three', 'one','two', 'three', 'one', 'two'],
                   'B' : ['h', 'h', 'h', 'h', 'f', 'f', 'f', 'f'],
                   'C' : np.arange(10,26,2),
                   'D' : np.random.randn(8),
                   'E':np.random.rand(8)})
print(df)
print(df.groupby('A')['C'].mean())
print(df.groupby('A')['D'].mean())
print(df.groupby(['A', 'B'])['D'].sum())
print(df.groupby(['A', 'B'])['E'].sum())
print(df.groupby('A').groups)
print(df.groupby(df.dtypes, axis=1).sum()) # 注意按照数值类型分组需要加上axis=1是按照列分组
print(df.groupby({'C':'col1', 'D':'col1'}, axis=1).sum())
print('====================================')
print(df.groupby('B').mean())
print(df.groupby('B').sum())
print(df.groupby('B').max())
print(df.groupby('B').min())

# 参考答案
print('以A分组,求出C,D的分组平均值为:\n',df.groupby('A').mean(),'\n------')
print('以A,B分组,求出D,E的分组求和为:\n',df.groupby(['A','B']).sum(),'\n------')
print('以A分组,筛选出分组后的第一组数据为:\n',df.groupby('A').groups,'\n------')
print('按照数值类型分组为:\n',df.groupby(df.dtypes,axis=1).sum(),'\n------')
print('将C,D作为一组分出来,并计算求和为:\n',df.groupby({'C':'r','D':'r'},axis=1).sum(),'\n------')
print('以B分组,求出每组的均值,求和,最大值,最小值:\n',df.groupby('B').agg([np.mean,np.sum,np.max,np.min]),'\n------')

12、分组转换及一般性“拆分-应用-合并”

import numpy as np
import pandas as pd

# transform / apply

# 数据分组转换,transform

df = pd.DataFrame({'data1':np.random.rand(5),
                  'data2':np.random.rand(5),
                  'key1':list('aabba'),
                  'key2':['one','two','one','two','one']})
print(df)
df2 = df.groupby('key1').mean()
print(df2)
print(pd.merge(df, df2, left_on='key1', right_index=True, how='left').add_prefix('mean_')) # .add_prefix('mean_'):添加前缀
print(df.groupby('key1').transform(np.mean))
# data1、data2每个位置元素取对应分组列的均值
# 字符串不能进行计算

# 一般化Groupby方法:apply

df = pd.DataFrame({'data1':np.random.rand(5),
                  'data2':np.random.rand(5),
                  'key1':list('aabba'),
                  'key2':['one','two','one','two','one']})

print(df.groupby('key1').apply(lambda x: x.describe()))
# apply直接运行其中的函数
# 这里为匿名函数,直接描述分组后的统计量

def f_df1(d,n):
    return(d.sort_index()[:n])
def f_df2(d,k1):
    return(d[k1])
print(df.groupby('key1').apply(f_df1,2),'\n')
print(df.groupby('key1').apply(f_df2,'data2'))
print(type(df.groupby('key1').apply(f_df2,'data2')))
# f_df1函数:返回排序后的前n行数据
# f_df2函数:返回分组后表的k1列,结果为Series,层次化索引
# 直接运行f_df函数
# 参数直接写在后面,也可以为.apply(f_df,n = 2))

13、分组转换及一般性“拆分-应用-合并”作业

import numpy as np
import pandas as pd

# 作业1:按要求创建Dataframe df,通过key分组求和,并将求和结果并在原df中

df = pd.DataFrame({'data1':np.random.rand(8),
                  'data2':np.random.rand(8),
                  'key':list('aabbabab')})
print(df)
r = df.groupby('key').sum().add_suffix('_mean')
print(r)
print(pd.merge(df, r, left_on='key', right_index=True))

14、透视表及交叉表

import numpy as np
import pandas as pd

# 类似excel数据透视 - pivot table / crosstab

# 透视表:pivot_table
# pd.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')

date = ['2017-5-1','2017-5-2','2017-5-3']*3
rng = pd.to_datetime(date)
df = pd.DataFrame({'date':rng,
                   'key':list('abcdabcda'),
                  'values':np.random.rand(9)*10})
print(df)
print(pd.pivot_table(df, values='values', index='date', columns='key', aggfunc=np.sum))
# data:DataFrame对象
# values:要聚合的列或列的列表
# index:数据透视表的index,从原数据的列中筛选
# columns:数据透视表的columns,从原数据的列中筛选
# aggfunc:用于聚合的函数,默认为numpy.mean,支持numpy计算方法
print(pd.pivot_table(df, values='values', index=['date', 'key'], aggfunc=np.min))
# 这里就分别以date、key共同做数据透视,值为values:统计不同(date,key)情况下values的平均值
# aggfunc=len(或者count):计数

# 交叉表:crosstab
# 默认情况下,crosstab计算因子的频率表,比如用于str的数据透视分析
# pd.crosstab(index, columns, values=None, rownames=None, colnames=None, aggfunc=None, margins=False, dropna=True, normalize=False)

df = pd.DataFrame({'A': [1, 2, 2, 2, 2],
                   'B': [3, 3, 4, 4, 4],
                   'C': [1, 1, np.nan, 1, 1]})
print(df)
print(pd.crosstab(df['A'],df['B']))
# 如果crosstab只接收两个Series,它将提供一个频率表。
# 用A的唯一值,统计B唯一值的出现次数
print(pd.crosstab(df['A'], df['B'], normalize=True))
# normalize:默认False,将所有值除以值的总和进行归一化 → 为True时候显示百分比
print(pd.crosstab(df['A'], df['B'], values=df['C'], aggfunc=np.sum))
# values:可选,根据因子聚合的值数组
# aggfunc:可选,如果未传递values数组,则计算频率表,如果传递数组,则按照指定计算
# 这里相当于以A和B界定分组,计算出每组中第三个系列C的值
print(pd.crosstab(df['A'],df['B'], values=df['C'], aggfunc=np.sum, margins=True))
# margins:布尔值,默认值False,添加行/列边距(小计)

15、透视表及交叉表作业

import numpy as np
import pandas as pd

# 作业1:按要求创建Dataframe df,并通过数据透视表或交叉表得到以下结果
# ① 以A列聚合,求出C,D的平均值
# ② 以A,B列聚合,求出D,E的均值、求和
# ③ 以B聚合,计算A列的元素频率

df = pd.DataFrame({'A' : ['one', 'two', 'three', 'one','two', 'three', 'one', 'two'],
                   'B' : ['h', 'h', 'h', 'h', 'f', 'f', 'f', 'f'],
                   'C' : np.arange(10,26,2),
                   'D' : np.random.randn(8),
                   'E':np.random.rand(8)})
print(df)
print(df.groupby('A').mean())
print(df.pivot_table(values=['C', 'D'], index='A', aggfunc=np.mean))
print(df.pivot_table(values=['C', 'D'], index='A', aggfunc='mean'))
print(df.pivot_table(values=['D', 'E'], index=['A', 'B'], aggfunc=['mean', 'sum']))
print(pd.crosstab(df['B'], df['A']))

16、文件读取

import numpy as np
import pandas as pd

# 核心:read_table, read_csv, read_excel

# 读取普通分隔数据:read_table
# 可以读取txt,csv

import os
os.chdir('C:/lyz/test')

data1 = pd.read_table('data1.txt', delimiter=',', engine='python')
print(data1)
# delimiter:用于拆分的字符,也可以用sep:sep = ','
# header:用做列名的序号,默认为0(第一行)
# index_col:指定某列为行索引,否则自动索引0, 1, .....

# read_table主要用于读取简单的数据,txt/csv

# 读取csv数据:read_csv
# 先熟悉一下excel怎么导出csv

data2 = pd.read_table('data2.csv', delimiter=',', engine='python', encoding='GBK')
print(data2)
# engine:使用的分析引擎。可以选择C或者是python。C引擎快但是Python引擎功能更加完备。
# encoding:指定字符集类型,即编码,通常指定为'utf-8'

# 大多数情况先将excel导出csv,再读取

print('==================================')
# 读取excel数据:read_excel
data = pd.read_excel('地市级党委书记数据库(2000-10).xlsx', sheet_name='中国人民共和国地市级党委书记数据库(2000-10)',header=0)
print(data)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值