玩转数据处理120题python|个人练习记录

从“早起Python” 公众号看到该文章,把内容拿下来练习一下,部分题目加了新解法。更多内容及标准答案请参考作者公众号,感谢作者的分享。

文章原地址:https://mp.weixin.qq.com/s/fvEDcAqWZ-HkoTMxi995dw

数据源下载:链接:https://pan.baidu.com/s/1MSqmWMiurHJSXyNBlJOEpw  密码:8mkx

一些输出结果在调试时有更改,不一定一一对应。

import pandas as pd
import numpy as np
import re
import matplotlib.pyplot as plt
import seaborn as sns
plt.style.use('ggplot')
#题目:将下面的字典创建为DataFrame
data = {"grammer":["Python","C","Java","GO",np.nan,"SQL","PHP","Python"],
       "score":[1,2,np.nan,4,5,6,7,10]}
df = pd.DataFrame(data)
df

# 题目:提取含有字符串"Python"的行
df[df['grammer'] == 'Python']
df[df['grammer'].fillna('').str.contains('Python')]    #contains 判断更合适,多个条件时'Python|Java|SQL'
#df

## 多列含有PYthon取出多列多行
df[df.isin(['Python','SQL']).sum(axis=1)>0]

#输出df的所有列名
df.columns.tolist()
df.columns

#题目:修改第二列列名为'popularity'
df.columns=['grammer','popularity']
df.rename(columns={'score':'popularity'},inplace=True)
df

#题目:统计grammer列中每种编程语言出现的次数
df['grammer'].value_counts()
df.groupby('grammer').count()

#题目:将空值用上下值的平均值填充
# pandas里有一个插值方法,就是计算缺失值上下两数的均值
df['popularity'].fillna(df['popularity'].interpolate())

#题目:提取popularity列中值大于3的行
df[df['popularity']>3]
df.query('popularity>3')

# 题目:按照grammer列进行去重
#df.groupby('grammer').tolist()
set(df['grammer'].tolist())
df['grammer'].drop_duplicates()

# 题目:计算popularity列平均值
#df.groupby('grammer')['popularity'].mean()
#df.groupby('grammer').apply(lambda x:x.mean())
df['popularity'].fillna(0).mean()   #注意na值处理

# 题目:将grammer列转换为list
df['grammer'].to_list()

# 题目:将DataFrame保存为EXCEL
df.to_csv('C://Users//JR//Desktop//测试.csv')
df

 

#题目:查看数据行列数
df.info()
df.shape

 

#题目:提取popularity列值大于3小于7的行
df[(3<df['popularity'])&(df['popularity']<7)]
df.query('3<popularity<7')

#题目:交换两列位置
tmp = df['grammer']
df['grammer'] = df['popularity']
df['popularity'] = tmp
df.rename(columns={'grammer':'popularity','popularity':'grammer'},inplace=True)

df.iloc[:,::-1]

df

 

#题目:提取popularity列最大值所在行
df[df['popularity'] == df['popularity'].max()]

# 题目:查看最后5行数据
df.tail()
df.iloc[-5:]
df[-5:]

#题目:删除最后一行数据
df.drop(df.popularity.count())
df.drop(['popularity'],axis=1)
df.drop(df.shape[0]-1)
df

# 题目:添加一行数据['Perl',6.6]
df.append({'popularity':6.6,'grammer':'Perl'},ignore_index=True)
#pd.concat([df,])
#添加的是字典类型,必须指定好键值

#题目:对数据按照"popularity"列值的大小进行排序
df.sort_values(['popularity'],ascending=False)

#题目:统计grammer列每个字符串的长度
df['len'] = df['grammer'].fillna('').map(lambda x: len(x))
df['len'] = df['grammer'].fillna('').apply(lambda x: len(x))
df

df.drop(['len'],axis=1)

#题目:读取本地EXCEL数据
path = 'C://Users//JR//Desktop//pandas120//21-50数据.xlsx'
df = pd.read_excel(path,encoding ='UTF8')
df.head(10)

#题目:查看df数据前5行
df.head()
df.iloc[:5]
df.loc[:5]

#题目:将salary列数据转换为最大值与最小值的平均值
df.head()

#题目:将salary列数据转换为最大值与最小值的平均值
#① 通过map和lambda直接选择
#df['salary'].map(lambda x:(int(x.split('k')[0]) + int(x.split('k-')[1][:-1]))*1000/2 )
#② 通过map调用func
def salary_mean(x):
    return (int(x.split('k')[0]) + int(x.split('k-')[1][:-1]))*1000/2
df['salary'] = df['salary'].map(salary_mean)
#③ 通过正则表达式
#'''for x,y in df.iterrows():
#    num2 = re.findall('\d+',y[2])
#    df['salary'] = (int(num2[0])+int(num2[1]))/2*1000'''
df.head()

# 题目:将数据根据学历进行分组并计算平均薪资
df.groupby('education')['salary'].mean().to_frame()
df.groupby('education').mean()

#题目:查看索引、数据类型和内存信息
df.info()

#题目:查看数值型列的描述统计
df.describe()

#题目:新增一列根据salary将数据分为三组
df['categories'] = pd.cut(df['salary'],np.arange(0,60000,10000),labels=['<1w','1w-2w','2w-3w','3w-4w','4w-5w'])
df[df['salary']>40000]
#labels=['<1w','1w-2w','2w-3w','3w-4w','4w-5w']

#题目:按照salary列对数据降序排列
df.sort_values('salary',ascending=False).head()

#题目:取出第33行数据
df.iloc[32]

#题目:计算salary列的中位数
np.median(df['salary'])

#题目:绘制薪资水平频率分布直方图
#①通过df内置的plot()函数进行绘图
#df['categories'].value_counts().sort_index().plot(kind='bar',rot=360,fontsize=15)
#②通过matplotlib进行绘图
plt.figure(figsize=(15,6))
'''sns.distplot(df['salary'],bins=10)
plt.xlabel('薪资',fontsize=15)
plt.title('薪资水平频率分布',fontsize=18)'''

#③通过plt的hist函数绘制
plt.hist(df['salary'])   #直接对Series进行计数绘图

#题目:绘制薪资水平密度曲线
plt.figure(figsize=(15,5))
df['salary'].plot(kind='kde')   #绘制概率密度函数

#题目:删除最后一列categories
df.drop('categories',axis=1).head()  #可选inplace参数

#题目:将df的第一列与第二列合并为新的一列
df['test'] = df['education'] + df['categories'].astype('str')
df.drop('test',axis=1,inplace=True)
df.head()

#题目:计算salary最大值与最小值之差
df['salary'].max()-df['salary'].min()
df[['salary']].apply(lambda x: x.max() - x.min())

#题目:将第一行与最后一行拼接
#选择一行的时候,且要保持为df结构,必须使用df[]
pd.concat([df[:1],df[-1:]])
#pd.concat([df[1:2], df[-1:]])

#题目:将第8行数据添加至末尾
df.append(df[7:8])  #通过一个df添加
df.append(df.iloc[7])  #通过一个Series添加

print(type(df[7:8]),type(df.iloc[7]))

# 题目:查看每列的数据类型
df.dtypes.to_frame()

#题目:将createTime列设置为索引
df1 = df.copy()
df1.set_index('createTime',inplace=True)  #可选参数inplace
df1.head()

#题目:生成一个和df长度相同的随机数dataframe
pd.DataFrame(np.random.randint(1,10,135))   #135个1~10之间的随机整数
pd.DataFrame(np.random.randn(135))  #一组符合标准正态的分数的数据
df2 = pd.DataFrame(np.random.rand(135))  #一组0-1的之间的数据
df2.head()

#题目:将上一题生成的dataframe与df合并
df = pd.concat([df,df2],axis=1) #concat函数默认连接行,通过axis指定成连接列#
df.head()

#题目:生成新的一列new为salary列减去之前生成随机数列
df['new'] = df['salary'] - df[0]
df.head()

#题目:检查数据中是否含有任何缺失值
df.isnull()
df.isnull().values.any()   #计算所选的数据是否有na值

#题目:将salary列类型转换为浮点数
df['salary'].astype(np.float64)
df.head()

#题目:计算salary大于10000的次数
df[df['salary']>10000].count()
len(df[df['salary']>10000])

#题目:查看每种学历出现的次数
df['education'].value_counts()
df.groupby('education').count()

#题目:查看education列共有几种学历
df['education'].unique()  #生成np.array
df['education'].nunique() #去重计数
len(df['education'].drop_duplicates())

#题目:提取salary与new列的和大于60000的最后3行
df[(df['salary']+df['new'])>6000].tail(3)
df[(df['salary']+df['new'])>6000].iloc[-3:]
#通过apply和axis对两个列进行直接相加
#np.where(condition)没有x,y的情况下,直接返回元组坐标
rowsums = df[['salary','new']].apply(np.sum, axis=1)
res = df.iloc[np.where(rowsums > 60000)[0][-3:], :]
df.iloc[np.where(rowsums > 60000)[0][-3:]]
#np.where(rowsums > 60000)[0][-3:]

#题目:使用绝对路径读取本地Excel数据
path = 'C://Users//JR//Desktop//pandas120//51-80数据.xls'
df = pd.read_excel(path,encoding = 'UTF8')
df.head(3)

#题目:查看每列数据缺失值情况
df.isnull().sum()
df.isna().sum()

#题目:提取日期列含有空值的行
df[df['日期'].isnull()]

#题目:输出每列缺失值具体行数
#这道题很提现数据框的价值!
for i in df.columns:
    if df[i].count()!=len(i):
        rows = df[df[i].isnull()].index.tolist()
        print('列名:"{}", 第{}行位置有缺失值'.format(i,rows))

#题目:删除所有存在缺失值的行
df.dropna(inplace=True)
df.isna().sum()

df[df['日期'].isnull()].index

#题目:绘制收盘价的折线图
df['收盘价(元)'].plot(figsize=(15,5))
plt.plot(df['收盘价(元)'])

#题目:同时绘制开盘价与收盘价
df[['收盘价(元)','开盘价(元)']].plot(figsize=(15,5))

#题目:绘制涨跌幅的直方图
plt.rcParams['axes.unicode_minus'] = False
df['涨跌幅(%)'].hist(bins=30)
#df['涨跌幅(%)'].plot(kind='hist',bins=30)

#题目:以data的列名创建一个dataframe
data = pd.DataFrame(np.random.randint(1,10,25).reshape(5,5),columns=list('sdfad'))
data1=pd.DataFrame(np.random.randint(1,10,25))
data1.head()

#题目:绘制换手率的密度曲线
df[df['换手率(%)'] != '--']['换手率(%)'].plot(kind = 'kde',xlim=(0,0.6))
sns.kdeplot(df[df['换手率(%)'] != '--']['换手率(%)'])

#题目:计算前一天与后一天收盘价的差值
df['收盘价(元)'].diff().head()

#题目:计算前一天与后一天收盘价变化率,环比比率
df['收盘价(元)'].pct_change().head()

#题目:设置日期为索引
df.set_index('日期',inplace=True)  #可选参数inplace
df.head()

#题目:以5个数据作为一个数据滑动窗口,在这个5个数据上取均值(收盘价)
df['收盘价(元)'].rolling(5).mean().head()  #默认是从右到左

#题目:以5个数据作为一个数据滑动窗口,计算这五个数据总和(收盘价)
df['收盘价(元)'].rolling(5).sum().head() 

#题目:将收盘价5日均线、20日均线与原始数据绘制在同一个图上
df['收盘价(元)'].rolling(5).mean().plot(figsize=(15,5))
df['收盘价(元)'].rolling(20).mean().plot(figsize=(15,5))
df['收盘价(元)'].plot()

#题目:按周为采样规则,取一周收盘价最大值
df['收盘价(元)'].plot(figsize=(15,5))
df['收盘价(元)'].resample('7D').max().plot()

#题目:将数据往后移动5天==>所有数据沿着timeindex向下移动5天
df.shift(5).head(10)

#题目:将数据向前移动5天
df.shift(-5).tail(10)

#题目:使用expending函数计算开盘价的移动窗口均值
df['开盘价(元)'].expanding(min_periods=1).mean().plot(figsize=(15,5))
df['开盘价(元)'].plot()

#题目:导入并查看pandas与numpy版本
print(pd.__version__)
print(np.__version__)

#题目:从NumPy数组创建DataFrame
df1 = pd.DataFrame(np.random.randint(1,5,5))
df1

#题目:从NumPy数组创建DataFrame
df2 = pd.DataFrame(np.arange(0,10,2))
df2

#题目:将df1,df2,df3按照行合并为新DataFrame
pd.concat([df1,df2,df3],axis=0,ignore_index=True)

#题目:将df1,df2,df3按照列合并为新DataFrame
pd.concat([df1,df2,df3],axis=1,ignore_index=True)

#题目:查看df所有数据的最小值、25%分位数、中位数、75%分位数、最大值
df.describe()
#df['0'].percentile(df, q=[0, 25, 50, 75, 100])

#df4 = pd.concat([df1,df2,df3],axis=1,ignore_index=True)
df4.columns = ['column1','column2','column3']
df4

#题目:提取第一列中不在第二列出现的数字
df4['column1'][~df4['column1'].isin(df4['column2'])]
df4[~df4['column1'].isin(df4['column2'])]['column1']

#题目:提取第一列和第二列出现频率最高的三个数字
tmp = df4['column1'].append(df4['column2'])
tmp2 = pd.concat([df4['column1'],df4['column2']])
tmp.value_counts()
tmp2.value_counts()

#题目:计算第一列数字前一个与后一个的差值
df4['column1'].diff

#题目:将col1,col2,clo3三列顺序颠倒
df4.iloc[::-1,::-1]

#题目:提取第一列位置在1,10,15的数字
#df4['column1'].loc[[1,3,5]]
df4['column1'].iloc[[1,2,3]]
df4['column1'].take([1,2,3])
df4.iloc[[1,2,3],0]

#题目:查找第一列的局部最大值位置
np.diff(np.sign(np.diff(df4['column3'])))
res = np.diff(np.sign(np.diff(df4['column3'])))
np.where(res==-2)[0]+1

#题目:按行计算df的每一行均值
df4.mean()  #列的平均值
df4.mean(axis=1)  #行的平均值

#题目:将数据按照第三列值的大小升序排列
df4.sort_values(['column3'],ascending = False)

#题目:将第一列大于50的数字修改为'高'
df4[df4['column1']>50] = '高'
df4

#题目:从CSV文件中读取指定数据
path1 = 'C://Users//JR//Desktop//pandas120//数据1_101-120涉及.csv'
path2 = 'C://Users//JR//Desktop//pandas120//数据2_101-120涉及.csv'

#共使用了‘read_csv’中三个不常用的方法:usecols:选择列,nrows选择行数,converters数据转化
#converters数据转化用法类似于map

# 从数据1中的前10行中读取positionName, salary两列
#df = pd.read_excel(path,encoding = 'UTF8')
df1 = pd.read_csv(path1,encoding = 'gbk',usecols=['positionId','positionName'],nrows =10)
df1

#从数据2中读取数据并在读取数据时将薪资大于10000的为改为高
df2 = pd.read_csv(path2,encoding = 'UTF8',converters={'薪资水平':lambda x: '高' if float(x) > 10000 else '低'})
df2.head()

#题目:从dataframe提取数据
#从上一题数据中,对薪资水平列每隔20行进行一次抽样
df2.iloc[::20]['薪资水平'].head()

#题目:将数据取消使用科学计数法
df = pd.DataFrame(np.random.random(10)**10, columns=['data'])
df.round(3)

#题目:将上一题的数据转换为百分数
df.style.format({'data': '{0:.2%}'.format})

#题目:查找上一题数据中第3大值的行号
np.where(df['data'].argsort()==len(df)-7)

#题目:按照多列对数据进行合并
df1= pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
'key2': ['K0', 'K1', 'K0', 'K1'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']})

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

#题目:按照多列对数据进行合并
pd.merge(df1,df2,on=['key1','key2'])

#题目:按照多列对数据进行合并,相当于left join
pd.merge(df1, df2, how='left', on=['key1', 'key2'])

#题目:再次读取数据1并显示所有的列
path1 = 'C://Users//JR//Desktop//pandas120//数据1_101-120涉及.csv'
df1 = pd.read_csv(path1,encoding = 'gbk')
pd.set_option("display.max.columns", None) # 显示所有列 None可改为其他任意值 
df1

#题目:查找secondType与thirdType值相等的行号
np.where(df1.secondType == df1.thirdType)

#题目:将上一题数据的salary列开根号
df1['salary'].apply(np.sqrt).head()

#题目:将上一题数据的linestaion列按_拆分
df1['linestaion'].str.split('_').head(8)

#题目:查看上一题数据中一共有多少列
len(df1.columns)
df1.shape[1]

#题目:提取industryField列以'数据'开头的行
np.where(df1['industryField'].str.startswith('数据'))
#df1[df1['industryField'].str.startswith('数据')]

#题目:以salary score 和 positionID制作数据透视
pd.pivot_table(df1,values=['salary','score'] ,index='positionId').head()
#pd.pivot_table(df,values=["salary","score"],index="positionId")

#题目:同时对salary、score两列进行计算
df1[["salary","score"]].agg([np.sum,np.mean,np.min]).round(1)

#题目:对不同列执行不同的计算
#对salary求平均,对score列求和
df1.agg({"salary":np.sum,"score":np.mean}).round(1)

#题目:计算并提取平均薪资最高的区
df1.groupby('district')['salary'].mean().sort_values()[-1:]
df1.groupby('district')['salary'].mean().sort_values().tail(1)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值