Pandas与Numpy的数据分析进阶题
Pandas与Numpy的数据分析进阶题
# 导入基础库
# pip install pandas
# pip install numpy
import pandas as pd
import numpy as np
1. 从列表和字典创建numpy Serires
list_arr = [i for i in range(5)]
# [0, 1, 2, 3, 4]
df_arr = pd.Series(list_arr)
df_arr
# 使用 ord() 函数将字符转换为其对应的 ASCII 值
print(ord('a'))
# 97
dict_arr = {i:j for i in ['a', 'b', 'c', 'd', 'e'] for j in range(1, 6) if ord(i) - j == 96}
# {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
df_arr = pd.Series(dict_arr)
df_arr
2. 基于字典数据和指定索引生成Dataframe
# 字典
data = {'name': ['xiaowang', 'xiaozhang'],
'gender': ['F', 'M'],
'age': [23, 27]}
indexs = ['e1', 'e2']
df = pd.DataFrame(data, index=indexs)
df
3. 生成时间序列作为索引的Dataframe
# 生成时间序列(时间间隔为秒)
dates = pd.date_range('today', periods=3, freq='S')
# 从标准正态分布(均值为0, 标准差为1)中随机抽取数字,生成3行3列的二维数组
arr = np.random.randn(3,3)
colnames = ['d1', 'd2', 'd3']
df = pd.DataFrame(arr, index=dates, columns=colnames)
df
4. Dataframe的基础信息统计
# 显示Dataframe的基础信息,行的数量,列名及该列的数据类型
df.info()
# 打印每列的统计信息
df.describe()
5. Dataframe的基本操作
(1)生成随机数矩阵和添加列名
# 生成1~100范围的3行4列随机数矩阵
data = np.random.randint(1, 100, size=(3, 4))
df = pd.DataFrame(data)
# 添加列名
df.columns = ['c1', 'c2', 'c3', 'c4']
df
(2)使用iloc取出Dataframe的列数据
# 取出前3列数据
df1 = df.iloc[:, :3]
df1
(3)使用iloc取出Dataframe的行数据
# 取出前2行数据
df1 = df.iloc[:2, :]
df1
(4)取出Dataframe的指定列数据
# 取出指定列数据
df3 = df[['c1', 'c2']]
# df3 = df.loc[:, ['c1', 'c2']]
df3
(5)取出Dataframe指定索引及指定列数据
# 取出索引为0, 2的c1和c2列数据
df4 = df.loc[df.index[[0, 2]], ['c1', 'c2']]
df4
(6)取出Dataframe大于指定阈值的数据
# 取出指定c1列大于50的行
df5 = df[df['c1'] > 50]
df5
(7)取出Dataframe指定范围的数据
# 取出c1列值在30到40的行
df6 = df[(df['c1'] >= 30) & (df['c1'] <= 40)]
# df6 = df[df['c1'].between(30, 40)]
df6
(8)修改Dataframe指定行列的数据
# 修改索引为0的c1列值
df.loc[0, 'c1'] = 50
df
(9)计算Dataframe某一列的和、添加新列、删除列
# 计算某一列的和
df['c1'].sum()
# 152
# 为dafaframe添加新的一列数据
types = ['A', 'B', 'A']
df['type'] = types
# 删除列
# df = df.drop('type')
df
(10)计算Dataframe各分组指定列的和
# 计算不同分组的指定列(c1)的和
df.groupby('type')['c1'].sum()
(11)计算Dataframe各分组指定列的平均值
# 计算不同分组的指定列(c1)的平均值
df.groupby('type')['c1'].mean()
(12)计算Dataframe各分组指定列的标准差
# 计算不同分组的指定列(c1)的标准差
df.groupby('type')['c1'].std()
(13)统计Dataframe各分组的数量及排序
# 统计每个分组的数量
df['type'].value_counts()
print(df)
# 按c1列降序排列,再按type列升序排列
df_sort = df.sort_values(by=['c1', 'type'], ascending=[True, False])
df_sort
(14)将Dataframe指定列数据进行重映射
# 将指定列的值重新映射
df['type_num'] = df['type'].map({'A': 1, 'B': 2, 'C':3})
df
(15)查询Dataframe各列数据类型及数据透视表
# 查看每列的数据类型
print(df.dtypes)
# 对每个类型的c1至c3列数值进行求和, 返回表格数值为对应类型的为c1至c3每列的和
df.pivot_table(index='type', values=['c1', 'c2', 'c3'], aggfunc='sum')
(16)去除Dataframe某列的重复数据
df = pd.DataFrame({'c1': [1, 2, 2, 3, 3, 4]})
df_nodup = df.drop_duplicates(subset='c1')
df_nodup
6. 获取减去对应行平均值的Dataframe
df = pd.DataFrame({'c1': [1, 2, 3],
'c2': [2, 3, 4],
'c3': [3, 4, 5]})
print(df)
# 打印每行的平均值
print(df.mean(axis=1))
# Dataframe的每个元素减去该行的平均值
df = df.sub(df.mean(axis=1), axis=0)
df
7. 获取Dataframe某一列元素之和最小、最大的列
# 获取Dataframe和最小/最大的一列
df = pd.DataFrame(np.random.random(size=(3,3)), columns=list('ABC'))
print(df)
# 最小一列
print(df.sum().idxmin())
# 'A'
# 最大一列
print(df.sum().idxmax())
# 'C'
8. 按指定列对Dataframe分组,获取每组大小排名前三的数据
# 按指定列C1对数据分组,并输出每组大小排名前三的数据
df = pd.DataFrame({'C1': list('AABBAAB'),
'C2': [10, 20, 15, 5, 30, 15, 20]})
print(df)
# 按C1列分组,获取C2前三大的数据
group_max_dict = df.groupby('C1')['C2'].nlargest(3)
for key,value in group_max_dict.items():
# key为一个元组,包含分组的类别和数据的索引
print(key[0], value)
# 对获取大小排名前三的数据求和
print(group_max_dict['A'].sum())
print(group_max_dict['B'].sum())
9. 获取Dataframe每个区段的求和结果
# 已知每个分数对应的学生数量,求指定步长10的分数段,grade分数列的和
df = pd.DataFrame({'grade': [80, 51, 90, 85, 60, 66, 88, 95],
'student_num': [2, 1, 2, 10, 3, 4, 12, 1]})
print(df)
df_sum = df.groupby(pd.cut(df['grade'], np.arange(0, 101, 10)))['student_num'].sum()
df_sum
10. 获取Dataframe前三大数值的行与列索引
# 求dataframe前三大数值的行列索引
df = pd.DataFrame(np.random.random(size=(6, 3)))
print(df)
# 重塑dataframe并降序排列
print(df.unstack().sort_values(ascending=False))
# 获取前三大数值的行列索引,并转换为列表
print(df.unstack().sort_values(ascending=False)[:3].index.to_list())
# [(0, 4), (1, 2), (0, 5)]
11. 获取Dataframe每个滑动窗口的平均值
# 计算每3位滑动窗口的平均值
df = pd.DataFrame({'group': list('AABBCCCABA'),
'value': [1, 2, 3, np.nan, 2, 3, np.nan, 1, 7, np.nan]})
print(df)
df_group = df.groupby(['group'])['value']
# 使用0填充nan, 以免计算时报错
df_group_remove_nan = df.fillna(0).groupby(['group'])['value']
# 计算每3个滑动窗口的平均值
df_mean = df_group.rolling(3, min_periods=1).sum() / df_group_remove_nan.rolling(3, min_periods=1).count()
# 索引重新排序
df_mean = df_mean.reset_index(level=0, drop=True).sort_index()
df_mean
12. 使用日期序列作为索引创建Series
# 生成start至end日期工作日的日期序列
# freq取值: B-工作日,D-日,W-周,M-每月最后一天,Y-每年最后一天
dates = pd.date_range(start='2025-01-01',end='2025-12-31', freq='B')
print(dates)
# 创建dates相同长度的随机数Series
series = pd.Series(np.random.random(len(dates)) * 100, index=dates)
series
# 对周一到周五的值求和
for week_idx in range(0,5):
print(series[series.index.weekday == week_idx].sum())
# 计算每周W以及每季度QE的平均值
for freq in ['W', 'QE']:
print(f"********* freq = {freq} **************")
print(series.resample(freq).mean())
# 按每4周一组进行分组,求最大值所对应的日期(即每四周值最大的日期)
series_max = series.groupby(pd.Grouper(freq='4W')).idxmax()
# 打印最大值日期对应的数值
for idx, key in series_max.items():
print(f"{idx}\t{series[key]}")
13. 按指定分割符拆分Dataframe的一列为两列
# 按指定字符"_"拆分一列字符串数据为两列
# 创建以_分割的样本编号+样本名称列表
list_sample = []
for i in range(1, 6):
for j in range(65, 65+6):
if j - i == 64:
list_sample.append(f'Sample{i}_{chr(j)}')
print(list_sample)
df = pd.DataFrame({'Sample': list_sample})
# 拆分Sample列
sample_column = df.Sample.str.split('_', expand=True)
# 添加列名
sample_column.columns = ['Sample_id', 'Sample_name']
# 加入原dataframe
df = df.join(sample_column)
# 删除原Sample列
df = df.drop('Sample', axis=1)
df
14. 设置Dataframe某列元素首字母大写
# 设置dataframe的一列首字母大写
df = pd.DataFrame({'C1': ['sample1', 'sample2', 'sample3']})
print(df)
df['C1'] = df['C1'].str.capitalize()
df
15. 替换Dataframe某列的特殊字符
# 去除dataframe一列的特殊符号(如/\().#等),只保留字母
df = pd.DataFrame({'C1': ['Xiaoming(1)', 'Wang.', '/Ming/']})
print(df)
df['C1'] = df['C1'].str.extract('([a-zA-Z\s]+)', expand=False).str.strip()
df
16. 根据字符串和数字索引生成Serires
# 生成字母和数字列表
letters = [f"{chr(i)}" for i in range(65, 65+3)]
numbers = list(range(3))
print(letters)
print(numbers)
# 构建字母+数字的组合索引的Series
indexs = pd.MultiIndex.from_product([letters, numbers])
series = pd.Series(np.random.rand(len(letters) * len(numbers)), index=indexs)
series
# 查看一级索引
print(series['A'])
print('\n')
# 查看二级索引为2的行
print(series['A', 2])
print('\n')
# 查看全部二级索引为0-2的行
print(series.loc[:, 0:2])
print('\n')
# 对一级和二级索引使用切片操作, 一级索引取从头到B, 二级索引取1-2
series.loc[pd.IndexSlice[:'B', 1:2]]
17. 根据字符串和数字索引生成Serires
# 生成字母和数字列表
letters = [f"{chr(i)}" for i in range(65, 65+3)]
numbers = list(range(3))
print(letters)
print(numbers)
# 构建字母+数字的组合索引的Series
indexs = pd.MultiIndex.from_product([letters, numbers])
series = pd.Series(np.random.rand(len(letters) * len(numbers)), index=indexs)
series
# 查看一级索引
print(series['A'])
print('\n')
# 查看二级索引为2的行
print(series['A', 2])
print('\n')
# 查看全部二级索引为0-2的行
print(series.loc[:, 0:2])
print('\n')
# 对一级和二级索引使用切片操作, 一级索引取从头到B, 二级索引取1-2
series.loc[pd.IndexSlice[:'B', 1:2]]