我是靠谱客的博主 单薄音响,最近开发中收集的这篇文章主要介绍Pandas练习(1-24题包含案例:苹果公司股票分析、美国各州人口分析),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

import pandas as pd
import numpy as np
from pandas import DataFrame
# Pandas api
https://www.cjavapy.com/article/276/

============================================

练习1:

使用多种方法创建以下Series,命名为s1:
语文 150
数学 150
英语 150
理综 300

============================================

# 列表创建
pd.Series(data=[150,150,150,300],index=['语文','数学','英语','理综'],name='s1')
语文
150
数学
150
英语
150
理综
300
Name: s1, dtype: int64
# 字典创建
dicts={'语文':150,'数学':150,'英语':150,'理综':300,}
s1=pd.Series(data=dicts,name='s1')
s1
语文
150
数学
150
英语
150
理综
300
Name: s1, dtype: int64

============================================

练习2:

使用多种方法对练习1创建的Series s1进行索引和切片:

索引:
数学 150

切片:
语文 150
数学 150
英语 150

============================================

s1.loc['数学']
150
s1.iloc[1]
150
s1[1]
150
s1['数学']
150
s1.values
array([150, 150, 150, 300], dtype=int64)
s1.keys()
Index(['语文', '数学', '英语', '理综'], dtype='object')
print(s1[:3])
语文
150
数学
150
英语
150
Name: s1, dtype: int64
s1[-2::-1]
英语
150
数学
150
语文
150
Name: s1, dtype: int64

============================================

练习3:

  1. 想一想Series运算和ndarray运算的规则有什么不同?

  2. 新建另一个索引包含“文综”的Series s2,并与s2进行多种算术操作。思考如何保存所有数据。

============================================

1.由于pandas的底层是集成了numpy,因此Series的底层数据就是使用ndarray来构建的,因此我们得到了一个Series后,就可以使用numpy中的函数,对数据进行操作。但是Series与ndarry不同的地方在于,Series中多了一个索引。

这些问题都是细节问题,只有熟悉了这些细节知识,对于我们熟练使用numpy和pandas都是由很大帮助的。Series的底层数据就是由ndarray来构建的,而DataFrame又是由一个个的Series堆积而成的,随意取出DataFrame每一行或者每一列数据,都是一个Series。

2.新建另一个索引包含“文综”的Series s2,并与s2进行多种算术操作。

s2=pd.Series(data=np.random.randint(100,150,size=5),index=['语文','数学','英语','理综','文综'],name='s2')
s2
语文
144
数学
103
英语
113
理综
115
文综
105
Name: s2, dtype: int32
s1
语文
150
数学
150
英语
150
理综
300
Name: s1, dtype: int64
s1+s2 # Pandas进行数据运算时,会按照索引进行一一对应,对应后进行相应的算术运算,没有对齐的位置就会用NaN进行填充。
数学
253.0
文综
NaN
理综
415.0
英语
263.0
语文
294.0
dtype: float64
# add函数就是指是s1+s2。对于s1来说,没有文综列,由于使用的是fill_value = 0,因此用 “0”来填充df1的e列,105+0=105
s1.add(s2,fill_value=0) # 加
数学
253.0
文综
105.0
理综
415.0
英语
263.0
语文
294.0
dtype: float64
s1*s2
数学
15450.0
文综
NaN
理综
34500.0
英语
16950.0
语文
21600.0
dtype: float64
s1.mul(s2,fill_value=1) # 乘
数学
15450.0
文综
105.0
理综
34500.0
英语
16950.0
语文
21600.0
dtype: float64
s1-s2
数学
47.0
文综
NaN
理综
185.0
英语
37.0
语文
6.0
dtype: float64
s1.sub(s2,fill_value=0) # 减
数学
47.0
文综
-105.0
理综
185.0
英语
37.0
语文
6.0
dtype: float64
s1/s2
数学
1.456311
文综
NaN
理综
2.608696
英语
1.327434
语文
1.041667
dtype: float64
s1.div(s2,fill_value=1) # 除
数学
1.456311
文综
0.009524
理综
2.608696
英语
1.327434
语文
1.041667
dtype: float64
s1//s2
数学
1.0
文综
NaN
理综
2.0
英语
1.0
语文
1.0
dtype: float64
s1.floordiv(s2,fill_value=1) #整除
数学
1.0
文综
0.0
理综
2.0
英语
1.0
语文
1.0
dtype: float64
s1%s2
数学
47.0
文综
NaN
理综
70.0
英语
37.0
语文
6.0
dtype: float64
s1.mod(s2,fill_value=0) # 取余
数学
47.0
文综
NaN
理综
70.0
英语
37.0
语文
6.0
dtype: float64
s2**s1
数学
8.425268e+301
文综
NaN
理综
inf
英语
9.157281e+307
语文
inf
dtype: float64
s2.pow(s1,fill_value=0) # 次幂
数学
8.425268e+301
文综
1.000000e+00
理综
inf
英语
9.157281e+307
语文
inf
dtype: float64

============================================

练习4:

根据以下考试成绩表,创建一个DataFrame,命名为df:


张三
李四
语文 150
0
数学 150
0
英语 150
0
理综 300
0

============================================

df=DataFrame({'张三':[150,150,150,300],'李四':[0,0,0,0]},index=['语文','数学','英语','理综'])
df
张三李四
语文1500
数学1500
英语1500
理综3000
df=pd.DataFrame({'张三':[150,150,150,300],'李四':[0,0,0,0]},index=['语文','数学','英语','理综'])
df
张三李四
语文1500
数学1500
英语1500
理综3000

============================================

练习5:

使用多种方法对ddd进行索引和切片,并比较其中的区别

============================================

# 通过列名取值
df.张三
语文
150
数学
150
英语
150
理综
300
Name: 张三, dtype: int64
df.李四
语文
0
数学
0
英语
0
理综
0
Name: 李四, dtype: int64
df['张三']
语文
150
数学
150
英语
150
理综
300
Name: 张三, dtype: int64
df[['张三','李四']]
张三李四
语文1500
数学1500
英语1500
理综3000
# 通过行名取值
df.loc['语文']
张三
150
李四
0
Name: 语文, dtype: int64
df.loc[['语文','数学']] # loc 全封闭,左闭右闭
张三李四
语文1500
数学1500
df.loc['语文':'理综']
张三李四
语文1500
数学1500
英语1500
理综3000
df.iloc[3]
张三
300
李四
0
Name: 理综, dtype: int64
df.iloc[0:4] # iloc里面必须是数字
iloc 半闭合,左闭右开
张三李四
语文1500
数学1500
英语1500
理综3000
df.iloc[0,1] # 第一行第二列的值
0

============================================

练习6:

  1. 假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值。

  2. 假设张三期中考试数学被发现作弊,要记为0分,如何实现?

  3. 李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?

  4. 后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?

============================================

ddd=pd.DataFrame(data=np.random.randint(90,150,size=(3,4)),index=['张三','李四','王五'],columns=['语文','英语','数学','python'])
ddd
语文英语数学python
张三141144102127
李四140128110135
王五1029392135
ddd2=pd.DataFrame(data=np.random.randint(90,150,size=(4,5)),index=['张三','李四','王五','刘六'],columns=['语文','英语','数学','python','java'])
ddd2
语文英语数学pythonjava
张三9490115141113
李四97127137127125
王五144123104105101
刘六109104129112147
  1. 假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值。
ddd+ddd2
javapython数学英语语文
刘六NaNNaNNaNNaNNaN
张三NaN268.0217.0234.0235.0
李四NaN262.0247.0255.0237.0
王五NaN240.0196.0216.0246.0
sums=ddd.add(ddd2,fill_value=0)
sums
javapython数学英语语文
刘六147.0112.0129.0104.0109.0
张三113.0268.0217.0234.0235.0
李四125.0262.0247.0255.0237.0
王五101.0240.0196.0216.0246.0
ddd.mean()
语文
127.666667
英语
121.666667
数学
101.333333
python
132.333333
dtype: float64
ddd2.mean()
语文
111.00
英语
111.00
数学
121.25
python
121.25
java
121.50
dtype: float64
sums.mean()
java
121.50
python
220.50
数学
197.25
英语
202.25
语文
206.75
dtype: float64
sums.mean(axis=0)
java
121.50
python
220.50
数学
197.25
英语
202.25
语文
206.75
dtype: float64
sums.mean(axis=1)
刘六
120.2
张三
213.4
李四
225.2
王五
199.8
dtype: float64
  1. 假设张三期中考试数学被发现作弊,要记为0分,如何实现?
ddd
语文英语数学python
张三1411440127
李四240228210235
王五1029392135
ddd.loc['张三','数学']=0
ddd
语文英语数学python
张三1411440127
李四240228210235
王五1029392135
  1. 李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?
ddd.loc['李四'] =ddd.loc['李四']+100 # 需要重新赋值
ddd
语文英语数学python
张三1411440127
李四240228210235
王五1029392135
ddd.loc['李四'].add(100.0) # 没有写入ddd中
语文
340.0
英语
328.0
数学
310.0
python
335.0
Name: 李四, dtype: float64
ddd
语文英语数学python
张三1411440127
李四240228210235
王五1029392135
  1. 后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?
ddd
语文英语数学python
张三1411440127
李四240228210235
王五1029392135
ddd=ddd+10
ddd
语文英语数学python
张三15115410137
李四250238220245
王五112103102145

============================================

练习7:

  1. 简述None与NaN的区别

  2. 假设张三李四参加模拟考试,但张三因为突然想明白人生放弃了英语考试,因此记为None,请据此创建一个DataFrame,命名为ddd3

  3. 老师决定根据用数学的分数填充张三的英语成绩,如何实现?
    用李四的英语成绩填充张三的英语成绩?

============================================

  1. 简述None与NaN的区别

在pandas中, 如果其他的数据都是数值类型, pandas会把None自动替换成NaN, 甚至能将s[s.isnull()]= None,和s.replace(NaN, None)操作的效果无效。这时需要用where函数才能进行替换。None能够直接被导入数据库作为空值处理, 包含NaN的数据导入时会报错。numpy和pandas的很多函数能处理NaN,但是如果遇到None就会报错。None和NaN都不能被pandas的groupby函数处理,包含None或者NaN的组都会被忽略。

  1. 假设张三李四参加模拟考试,但张三因为突然想明白人生放弃了英语考试,因此记为None,请据此创建一个DataFrame,命名为ddd3
ddd3=pd.DataFrame(data=np.random.randint(50,150,size=(2,4)),index=['张三','李四'],columns=['语文','数学','英语','python'],dtype=float)
ddd3
语文数学英语python
张三133.060.0116.052.0
李四114.065.099.074.0
ddd3.loc['张三','英语']=np.nan
ddd3
语文数学英语python
张三133.060.0NaN52.0
李四114.065.099.074.0
  1. 老师决定根据用数学的分数填充张三的英语成绩,如何实现?
    用李四的英语成绩填充张三的英语成绩?
ddd3.loc['张三','英语']=ddd3.loc['张三','数学']
ddd3
语文数学英语python
张三133.060.060.052.0
李四114.065.099.074.0
ddd3.loc['张三','英语']=ddd3.loc['李四','英语']
ddd3
语文数学英语python
张三133.060.099.052.0
李四114.065.099.074.0

============================================

练习8:

  1. 创建一个DataFrame,表示出张三李四期中期末各科成绩

============================================

隐式构造

Columns=[['期中','期中','期中','期中','期末','期末','期末','期末'],['语文','数学','英语','物理','语文','数学','英语','物理']]
index=[['张三','张三','张三','李四','李四','李四'],np.arange(6)]
df=pd.DataFrame(data=np.random.randint(100,150,size=(6,8)),index=index,columns=Columns)
df
期中期末
语文数学英语物理语文数学英语物理
张三0116140108113138136137102
1134110136141100144120145
2110146108127116146113148
李四3146130124118135130135108
4110142116122143121127121
5106107136140106126100120

显示构造

  • 使用数组 pd.MultiIndex.from_arrays
  • 使用tuple pd.MultiIndex.from_tuples
  • 使用product pd.MultiIndex.from_product

使用数组 pd.MultiIndex.from_arrays

Columns=pd.MultiIndex.from_arrays([['期中','期中','期中','期中','期末','期末','期末','期末'],['语文','数学','英语','物理','语文','数学','英语','物理']])
index=pd.MultiIndex.from_arrays([['张三','张三','张三','李四','李四','李四'],np.arange(6)])
df1=pd.DataFrame(data=np.random.randint(100,150,size=(6,8)),index=index,columns=Columns)
df1
期中期末
语文数学英语物理语文数学英语物理
张三0129119146109145137132134
1143130103134145103134132
2114129131104102115136112
李四3130148129132148104108102
4124126117135110134113122
5136119137136119149146123

使用元组 pd.MultiIndex.from_tuples

Columns=pd.MultiIndex.from_tuples([('期中','语文'),('期中','数学'),('期中','英语'),('期中','物理'),('期末','语文'),('期末','数学'),('期末','英语'),('期末','物理')])
index=pd.MultiIndex.from_tuples([('张三',0),('张三',1),('张三',2),('李四',3),('李四',4),('李四',5)])
df2=pd.DataFrame(data=np.random.randint(100,150,size=(6,8)),index=index,columns=Columns)
df2
期中期末
语文数学英语物理语文数学英语物理
张三0115119117106147110113144
1129108130142103100111141
2125147111119143119107105
李四3144146149144103106119136
4113128129104131134103144
5110137120148119113122128

使用product pd.MultiIndex.from_product

Columns=pd.MultiIndex.from_product([['期中','期末'],['语文','数学','英语','物理']])
index=pd.MultiIndex.from_product([['张三','李四'],np.arange(3)])
df3=pd.DataFrame(data=np.random.randint(100,150,size=(6,8)),index=index,columns=Columns)
df3
期中期末
语文数学英语物理语文数学英语物理
张三0139109131130110118138103
1144112136142124123117105
2147120126120100118127140
李四0142125140144141135102114
1116144109144123107136128
2102131131109116118134122
# 使用Series创建多层索引(隐式)
s = pd.Series([80, 90, 82, 92],index=[['a', 'a', 'b', 'b'],['期中', '期末', '期中', '期末']])
s
a
期中
80
期末
90
b
期中
82
期末
92
dtype: int64
s.loc['a']['期末']
90

============================================

练习9:

  1. 分析比较Series和DataFrame各种索引的方式,熟练掌握.loc()方法

  2. 假设张三再一次在期中考试的时候因为特殊原因放弃英语考试,如何实现?

============================================

  1. 分析比较Series和DataFrame各种索引的方式,熟练掌握.loc()方法

Series和DataFrame相比没有列索引。

Series

Series是一种类似于一维数组的对象,由一组数据以及一组与之相关的数据标签组成。仅由一组数据即可产生最简单的Series

DataFrame

DataFrame是一个表格型的数据,含有一组有序的列,每列可以是不同的值类型。Pandas的dataframe可以存储许多种不同的数据类型,并且每一个坐标轴都有自己的标签。你可以把它想象成一个series的字典项。

Columns=pd.MultiIndex.from_product([['期中','期末'],['语文','数学','英语','物理']])
index=pd.MultiIndex.from_product([['张三','李四'],np.arange(3)])
df4=pd.DataFrame(data=np.random.randint(100,150,size=(6,8)),index=index,columns=Columns,dtype=float)
df4
期中期末
语文数学英语物理语文数学英语物理
张三0125.0112.0129.0142.0116.0138.0104.0149.0
1148.0113.0141.0120.0147.0117.0118.0120.0
2138.0140.0130.0144.0123.0140.0102.0112.0
李四0119.0112.0119.0149.0128.0119.0117.0119.0
1139.0147.0132.0147.0121.0122.0121.0142.0
2143.0103.0128.0134.0106.0126.0138.0142.0
  1. 假设张三再一次在期中考试的时候因为特殊原因放弃英语考试,如何实现?
df4.loc['张三','期中']['英语'][:]=0
df4
期中期末
语文数学英语物理语文数学英语物理
张三0125.0112.00.0142.0116.0138.0104.0149.0
1148.0113.00.0120.0147.0117.0118.0120.0
2138.0140.00.0144.0123.0140.0102.0112.0
李四0119.0112.0119.0149.0128.0119.0117.0119.0
1139.0147.0132.0147.0121.0122.0121.0142.0
2143.0103.0128.0134.0106.0126.0138.0142.0
type(df4.loc['张三','期中']['英语'][0])
numpy.int32
ddd3.loc['张三','英语']=None
ddd3
语文数学英语python
张三133.060.0NaN52.0
李四114.065.099.074.0

============================================

练习10:

  1. 使用unstack()将ddd变为两行,分别为期中期末

  2. 使用unstack()将ddd变为四行,分别为四个科目

============================================

df4
期中期末
语文数学英语物理语文数学英语物理
张三0125.0112.00.0142.0116.0138.0104.0149.0
1148.0113.00.0120.0147.0117.0118.0120.0
2138.0140.00.0144.0123.0140.0102.0112.0
李四0119.0112.0119.0149.0128.0119.0117.0119.0
1139.0147.0132.0147.0121.0122.0121.0142.0
2143.0103.0128.0134.0106.0126.0138.0142.0
  1. 使用unstack()将ddd变为两行,分别为期中期末
df4.unstack(level=1).stack(level=0).unstack(level=0)
数学物理...英语语文
01201...12012
张三李四张三李四张三李四张三李四张三李四...张三李四张三李四张三李四张三李四张三李四
期中112.0112.0113.0147.0140.0103.0142.0149.0120.0147.0...0.0132.00.0128.0125.0119.0148.0139.0138.0143.0
期末138.0119.0117.0122.0140.0126.0149.0119.0120.0142.0...118.0121.0102.0138.0116.0128.0147.0121.0123.0106.0

2 rows × 24 columns

  1. 使用unstack()将ddd变为四行,分别为四个科目
df4.unstack(level=0).stack(level=1).unstack(level=0)
期中期末
张三李四张三李四
012012012012
数学112.0113.0140.0112.0147.0103.0138.0117.0140.0119.0122.0126.0
物理142.0120.0144.0149.0147.0134.0149.0120.0112.0119.0142.0142.0
英语0.00.00.0119.0132.0128.0104.0118.0102.0117.0121.0138.0
语文125.0148.0138.0119.0139.0143.0116.0147.0123.0128.0121.0106.0

============================================

练习11:

  1. 计算各个科目期中期末平均成绩

  2. 计算各科目张三李四的最高分

============================================

  1. 计算各个科目期中期末平均成绩
df4
期中期末
语文数学英语物理语文数学英语物理
张三0125.0112.00.0142.0116.0138.0104.0149.0
1148.0113.00.0120.0147.0117.0118.0120.0
2138.0140.00.0144.0123.0140.0102.0112.0
李四0119.0112.0119.0149.0128.0119.0117.0119.0
1139.0147.0132.0147.0121.0122.0121.0142.0
2143.0103.0128.0134.0106.0126.0138.0142.0
df4.mean()
期中
语文
135.333333
数学
121.166667
英语
63.166667
物理
139.333333
期末
语文
123.500000
数学
127.000000
英语
116.666667
物理
130.666667
dtype: float64
  1. 计算各科目张三李四的最高分
df4.max(level=0)
期中期末
语文数学英语物理语文数学英语物理
张三148.0140.00.0144.0147.0140.0118.0149.0
李四143.0147.0132.0149.0128.0126.0138.0142.0

============================================

练习12:

  1. 生成2个3*3的矩阵,对其分别进行两个维度上的级联

============================================

a=np.zeros((3,3))
a
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
b=np.ones((3,3))
b
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
np.concatenate((a,b),axis=0) # 垂直合并
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
np.concatenate((a,b),axis=1) # 水平合并
array([[0., 0., 0., 1., 1., 1.],
[0., 0., 0., 1., 1., 1.],
[0., 0., 0., 1., 1., 1.]])

============================================

练习13:

  1. 想一想级联的应用场景?
    就是将多个DataFrame进行横向或者纵向的拼接

  2. 使用昨天的知识,建立一个期中考试张三、李四的成绩表ddd

  3. 假设新增考试学科"计算机",如何实现?

  4. 新增王老五同学的成绩,如何实现?

============================================

  1. 想一想级联的应用场景?

就是将多个DataFrame进行横向或者纵向的拼接

  1. 使用昨天的知识,建立一个期中考试张三、李四的成绩表ddd
# 简单创建
df5=pd.DataFrame(data=np.random.randint(100,150,size=(2,4)),index=['张三','李四'],columns=['语文','数学','英语','道德'])
df5
语文数学英语道德
张三102131102119
李四120108105140
# 层级化索引
columns=pd.MultiIndex.from_product([['期中'],['语文','数学','英语','道德']])
index=['张三','李四']
df6=pd.DataFrame(data=np.random.randint(100,150,size=(2,4)),index=index,columns=columns)
df6
期中
语文数学英语道德
张三114145100126
李四127134104128
  1. 假设新增考试学科"计算机",如何实现?
df5
语文数学英语道德
张三118103108120
李四128133111118
df5['计算机']=0
df5
语文数学英语道德计算机
张三1181031081200
李四1281331111180
  1. 新增王老五同学的成绩,如何实现?
df5.loc['王老五']=[110,100,90,120]
df5
语文数学英语道德
张三102131102119
李四120108105140
王老五11010090120

============================================

练习14:

假设【期末】考试ddd2的成绩没有张三的,只有李四、王老五、赵小六的,使用多种方法级联

============================================

ddd2=pd.DataFrame(data=np.random.randint(100,150,size=(3,5)),columns=pd.MultiIndex.from_product([['期末'],['语文','数学','英语','python','java']]),index=['李四','王老五','赵小六'])
ddd2
ddd3=pd.DataFrame(data=np.random.randint(100,150,size=(1,4)),index=['张三'],columns=[['期末','期末','期末','期末'],['语文','数学','英语','python']])
ddd3
期末
语文数学英语python
张三145142141109

简单级联(外连接)

rs=pd.concat([ddd2,ddd3],axis=0)
rs
期末
javapython数学英语语文
李四131.0132134123142
王老五124.0112149124120
赵小六141.0132132136120
张三NaN109142141145
rs1=pd.concat([ddd2,ddd3])
rs1
期末
javapython数学英语语文
李四131.0132134123142
王老五124.0112149124120
赵小六141.0132132136120
张三NaN109142141145
rs=pd.concat([ddd2,ddd3],axis=1) # 错误示范
rs
C:UsersCdny_tanxin_134Anaconda3libsite-packagesipykernel_launcher.py:1: FutureWarning: Sorting because non-concatenation axis is not aligned. A future version
of pandas will change to not sort by default.
To accept the future behavior, pass 'sort=False'.
To retain the current behavior and silence the warning, pass 'sort=True'.
"""Entry point for launching an IPython kernel.
期末
语文数学英语pythonjava语文数学英语python
张三NaNNaNNaNNaNNaN145.0142.0141.0109.0
李四142.0134.0123.0132.0131.0NaNNaNNaNNaN
王老五120.0149.0124.0112.0124.0NaNNaNNaNNaN
赵小六120.0132.0136.0132.0141.0NaNNaNNaNNaN

多层索引 keys

pd.concat([ddd2,ddd3],keys=['x','y'])
期末
javapython数学英语语文
x李四131.0132134123142
王老五124.0112149124120
赵小六141.0132132136120
y张三NaN109142141145

内连接:只连接匹配的项(join=inner)

pd.concat((ddd2,ddd3),join='inner',axis=0)
期末
python数学英语语文
李四132134123142
王老五112149124120
赵小六132132136120
张三109142141145

连接指定轴 join_axes

pd.concat([ddd2,ddd3],join_axes=[ddd2.columns])
期末
语文数学英语pythonjava
李四142134123132131.0
王老五120149124112124.0
赵小六120132136132141.0
张三145142141109NaN

============================================

练习15:

新建一个只有张三李四王老五的期末考试成绩单ddd3,使用append()与期中考试成绩表ddd级联

============================================

ddd4=pd.DataFrame(data=np.random.randint(100,150,size=(3,5)),columns=pd.MultiIndex.from_product([['期末'],['语文','数学','英语','python','java']]),index=['张三','李四','王老五'])
ddd4
期末
语文数学英语pythonjava
张三112110142143123
李四119108127132122
王老五140119115109136
ddd5=pd.DataFrame(data=np.random.randint(100,150,size=(3,4)),index=['王大锤','狗子','杨子'],columns=[['期中','期中','期中','期中'],['国学','道德','c++','c#']])
ddd5
期中
国学道德c++c#
王大锤147148146117
狗子118124102102
杨子107106140111
ddd4.append(ddd5)
期中期末
c#c++国学道德javapython数学英语语文
张三NaNNaNNaNNaN123.0143.0110.0142.0112.0
李四NaNNaNNaNNaN122.0132.0108.0127.0119.0
王老五NaNNaNNaNNaN136.0109.0119.0115.0140.0
王大锤117.0146.0147.0148.0NaNNaNNaNNaNNaN
狗子102.0102.0118.0124.0NaNNaNNaNNaNNaN
杨子111.0140.0107.0106.0NaNNaNNaNNaNNaN

============================================

练习16:

  1. 假设有两份成绩单,除了ddd是张三李四王老五之外,还有ddd4是张三和赵小六的成绩单,如何合并?

  2. 如果ddd4中张三的名字被打错了,成为了张十三,怎么办?

  3. 自行练习多对一,多对多的情况

  4. 自学left_index,right_index

============================================

ddd=pd.DataFrame(data=np.random.randint(100,150,size=(3,5)),columns=pd.MultiIndex.from_product([['期末'],['语文','数学','英语','python','java']]),index=['李四','王老五','张三'])
ddd4=pd.DataFrame(data=np.random.randint(100,150,size=(2,4)),index=['张三','赵小六'],columns=[['期末','期末','期末','期末'],['语文','数学','英语','python']])
display(ddd,ddd4)
期末
语文数学英语pythonjava
李四116140145134104
王老五140142123129123
张三119131145134117
期末
语文数学英语python
张三125135143132
赵小六131118139115
  1. 假设有两份成绩单,除了ddd是张三李四王老五之外,还有ddd4是张三和赵小六的成绩单,如何合并?
ddd.merge(ddd4,how='outer') # 外合并
期末
语文数学英语pythonjava
0116140145134104.0
1140142123129123.0
2119131145134117.0
3125135143132NaN
4131118139115NaN

============================================

练习17:

  1. 如果只有张三赵小六语数英三个科目的成绩,如何合并?

  2. 考虑应用情景,使用多种方式合并ddd与ddd4

============================================

ddd7=pd.DataFrame(data=np.random.randint(100,150,size=(3,5)),columns=pd.MultiIndex.from_product([['期末'],['语文','数学','英语','python','java']]),index=['李四','王老五','张三'])
ddd8=pd.DataFrame(data=np.random.randint(100,150,size=(2,3)),index=['张三','赵小六'],columns=[['期末','期末','期末'],['语文','数学','英语']])
display(ddd7,ddd8)
期末
语文数学英语pythonjava
李四144109122113129
王老五116112121145114
张三138132149144122
期末
语文数学英语
张三104110124
赵小六147115123
ddd7.merge(ddd8,how='inner')
期末
语文数学英语pythonjava
ddd7.merge(ddd8,how='left')
期末
语文数学英语pythonjava
0144109122113129
1116112121145114
2138132149144122
ddd7.merge(ddd8,how='right')
期末
语文数学英语pythonjava
0104110124NaNNaN
1147115123NaNNaN
ddd7.merge(ddd8,how='outer')
期末
语文数学英语pythonjava
0144109122113.0129.0
1116112121145.0114.0
2138132149144.0122.0
3104110124NaNNaN
4147115123NaNNaN

============================================

练习18:

假设有两个同学都叫李四,ddd5、ddd6都是张三和李四的成绩表,如何合并?

============================================

ddd9=pd.DataFrame(data={'姓名':['李四','李四'],'体育':[80,100]})
ddd9
姓名体育
0李四80
1李四100
ddd5=pd.DataFrame(data={'姓名':['张三','李四'],'语文':[70,110]})
ddd5
姓名语文
0张三70
1李四110
ddd6=pd.DataFrame(data={'姓名':['张三','李四'],'数学':[80,10]})
ddd6
姓名数学
0张三80
1李四10
ddd=ddd5.merge(ddd6,on=['姓名'])
ddd
姓名语文数学
0张三7080
1李四11010
ddd.merge(ddd9,on=['姓名'],how='outer')
姓名语文数学体育
0张三7080NaN
1李四1101080.0
2李四11010100.0

============================================

练习19:

假设张三李四的课表里有满分的情况,老师认为是作弊,把所有满分的情况(包括150,300分)都记0分,如何实现?

============================================

data={'语文':[150,140],'数学':[140,150],'理综':[100,300]}
index=['张三','李四']
df=pd.DataFrame(data=data,index=index)
df
语文数学理综
张三150140100
李四140150300
df.replace({150:0,300:0},inplace=True)
df
语文数学理综
张三0140100
李四14000

============================================

练习20:

新增两列,分别为张三、李四的成绩状态,如果分数低于90,则为"failed",如果分数高于120,则为"excellent",其他则为"pass"
【提示】使用函数作为map的参数

============================================

def start(number):
if number>=120:
return 'excellent'
elif number<=90:
return 'failed'
else:
return 'pass'
data={'语文':[150,140],'数学':[140,150],'理综':[100,300]}
index=['张三','李四']
df=pd.DataFrame(data=data,index=index)
df
语文数学理综
张三150140100
李四140150300
df['start']=df['语文'].map(start)
df
语文数学理综start
张三150140100excellent
李四140150300excellent

============================================

练习21:

新建一个形状为10000*3的标准正态分布的DataFrame(np.random.randn),去除掉所有满足以下情况的行:其中任一元素绝对值大于3倍标准差

============================================

# 删除特定索引df.drop(labels,inplace = True)
df = pd.DataFrame(data=np.random.randn(10000,3))
cond = (df.abs()>(df.std()*3))
df.drop(labels=cond,inplace=True)
df.size
29991
df
012
3-0.5608381.913639-0.850757
40.989591-0.2074251.311457
5-0.2900310.3560491.197904
6-0.111649-0.4439341.229848
71.2094230.058577-0.181224
80.426214-1.825834-0.678655
9-1.266983-0.3743290.331815
10-0.526846-0.739292-0.063582
111.4363402.5381600.320171
121.093935-2.153419-0.217156
13-0.0680600.8350910.949730
14-0.138401-0.9580200.760745
15-2.1860112.1984531.508536
16-0.3785000.093705-0.660473
17-0.7218970.044228-0.270545
180.100407-0.398133-0.303283
19-0.758901-0.3282821.745042
20-0.382283-0.9295210.672403
210.8890000.300203-1.334921
220.3089710.7729291.379992
230.1878690.0668402.245180
24-0.248760-0.7059600.251919
250.441756-0.3537190.303286
260.968774-0.540734-0.732226
27-0.018883-0.683282-1.280041
28-0.333049-1.2133351.476833
290.1157160.214476-1.225241
301.124623-1.6889031.494815
311.546405-0.4751590.975128
32-0.1960510.908948-1.140523
............
99700.437677-0.7681311.704868
99710.247849-0.178058-0.208872
9972-1.909071-1.3063130.469814
9973-1.3278840.0725890.621892
99741.2173620.971040-1.841854
9975-0.833471-1.8134850.663718
99760.675048-0.0225740.324323
9977-1.474949-0.8652520.461087
99780.751405-0.5537430.864374
99790.5372902.9429151.004630
99800.504262-0.708962-0.660302
9981-0.847101-0.901427-1.138125
99820.1238070.6985790.071285
9983-1.175523-0.2903410.856139
99841.100372-0.639877-2.475960
99850.3113920.672191-0.999938
99860.918819-0.802126-0.104189
9987-0.2289781.3726510.353532
9988-0.8986500.8071931.183023
99890.9473041.574362-0.553031
99901.1070250.9318370.943330
9991-0.0624260.2945280.991291
99921.1902450.7672820.228312
99931.735471-0.567979-0.103361
9994-0.474085-0.249444-0.437047
9995-0.676380-0.1163741.800827
9996-0.0318090.6199270.039225
99970.826990-0.747790-1.193965
99980.538697-0.7129971.414235
99991.8312320.5807010.285351

9997 rows × 3 columns

============================================

练习22:

假设有张三李四王老五的期中考试成绩ddd2,对着三名同学随机排序

============================================

使用.take()函数排序

可以借助np.random.permutation()函数随机排序 permutation:产生0到n-1的所有整数的随机排列

ddd2=pd.DataFrame(data={'语文':[120,117,90],'数学':[80,120,99],'英语':[119,150,70]},index=['张三','李四','王老五'])
ddd2
语文数学英语
张三12080119
李四117120150
王老五909970
ddd2.take(np.random.randint(3,size=3),axis=1) # 随机重排列归还 axis=1 列
语文英语英语
张三120119119
李四117150150
王老五907070
ddd2.take(np.random.randint(3,size=3),axis=0) # 随机重排列归还 axis=0 行
语文数学英语
张三12080119
张三12080119
王老五909970
ints=np.random.permutation(3) # 随机重排列(不会重复)不归还 行
ddd2.take(ints,axis=0)
语文数学英语
王老五909970
张三12080119
李四117120150
ints=np.random.permutation(3) # 随机重排列(不会重复)不归还 列
ddd2.take(ints,axis=1)
语文数学英语
张三12080119
李四117120150
王老五909970

============================================

练习23:

假设菜市场张大妈在卖菜,有以下属性:

菜品(item):萝卜,白菜,辣椒,冬瓜

颜色(color):白,青,红

重量(weight)

价格(price)

  1. 要求以属性作为列索引,新建一个ddd
  2. 对ddd进行聚合操作,求出颜色为白色的价格总和
  3. 对ddd进行聚合操作,求出萝卜的所有重量(包括白萝卜,胡萝卜,青萝卜)以及平均价格
  4. 使用merge合并总重量及平均价格

============================================

# 1
ddd = DataFrame({'item': ['萝卜', '萝卜','萝卜', '白菜', '白菜','辣椒','辣椒','辣椒', '冬瓜', '冬瓜'],
'color': ['白', '红', '青', '青', '白', '青', '红', '白',
'青', '白'],
'weight': [60, 70, 40, 50, 60, 100, 80, 20, 200, 150],
'price': [2.68, 3.98, 4.98, 1.28, 1.58, 7.98, 8.88, 12.28, 1.28, 1.58]
})
ddd
itemcolorweightprice
0萝卜602.68
1萝卜703.98
2萝卜404.98
3白菜501.28
4白菜601.58
5辣椒1007.98
6辣椒808.88
7辣椒2012.28
8冬瓜2001.28
9冬瓜1501.58
# 2
ddd.groupby('color',as_index=False)['price'].sum()
colorprice
018.12
112.86
215.52
# 3
sums=ddd.groupby(['color','item'],as_index=False)['weight'].sum()
sum_df=sums.add_prefix('sum_')
avg=ddd.groupby(['color','item'],as_index=False)['price'].mean()
avg_df=avg.add_prefix('avg_')
display(sum_df,avg_df)
sum_colorsum_itemsum_weight
0冬瓜150
1白菜60
2萝卜60
3辣椒20
4萝卜70
5辣椒80
6冬瓜200
7白菜50
8萝卜40
9辣椒100
avg_coloravg_itemavg_price
0冬瓜1.58
1白菜1.58
2萝卜2.68
3辣椒12.28
4萝卜3.98
5辣椒8.88
6冬瓜1.28
7白菜1.28
8萝卜4.98
9辣椒7.98
#4.
df_data=sums.merge(avg,how='left')
df_data.add_prefix('df_')
df_colordf_itemdf_weightdf_price
0冬瓜1501.58
1白菜601.58
2萝卜602.68
3辣椒2012.28
4萝卜703.98
5辣椒808.88
6冬瓜2001.28
7白菜501.28
8萝卜404.98
9辣椒1007.98

============================================

练习24:

使用transform与apply实现练习23的功能

============================================


1+1

案例分析:苹果公司股票分析

# 导包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 查看数据
AAPL=pd.read_csv('../data/AAPL.csv')
AAPL.head()
DateOpenHighLowCloseAdj CloseVolume
01980-12-120.5133930.5156250.5133930.5133930.421597117258400
11980-12-150.4888390.4888390.4866070.4866070.39960143971200
21980-12-160.4531250.4531250.4508930.4508930.37027226432000
31980-12-170.4620540.4642860.4620540.4620540.37943721610400
41980-12-180.4754460.4776790.4754460.4754460.39043618362400
# 查看数据类型
AAPL.dtypes
Date
object
Open
float64
High
float64
Low
float64
Close
float64
Adj Close
float64
Volume
int64
dtype: object
# 将Date列转换为时间类型
date=AAPL['Date']
AAPL['Date']=pd.to_datetime(date)
AAPL.dtypes
Date
datetime64[ns]
Open
float64
High
float64
Low
float64
Close
float64
Adj Close
float64
Volume
int64
dtype: object
# 将'Date'设置为行索引
AAPL_date=AAPL.set_index('Date')
AAPL_date.head()
AAPL_date.index
DatetimeIndex(['1980-12-12', '1980-12-15', '1980-12-16', '1980-12-17',
'1980-12-18', '1980-12-19', '1980-12-22', '1980-12-23',
'1980-12-24', '1980-12-26',
...
'2017-10-10', '2017-10-11', '2017-10-12', '2017-10-13',
'2017-10-16', '2017-10-17', '2017-10-18', '2017-10-19',
'2017-10-20', '2017-10-23'],
dtype='datetime64[ns]', name='Date', length=9296, freq=None)
# 绘制折线图
ax_=AAPL_date['Adj Close'].plot(kind='line',figsize=(15,10))
ax_.figure.tight_layout()
ax_.set_xticklabels(AAPL_date.index)
[Text(723546,0,'1980-12-12 00:00:00'),
Text(725007,0,'1980-12-15 00:00:00'),
Text(726468,0,'1980-12-16 00:00:00'),
Text(727929,0,'1980-12-17 00:00:00'),
Text(729390,0,'1980-12-18 00:00:00'),
Text(730851,0,'1980-12-19 00:00:00'),
Text(732312,0,'1980-12-22 00:00:00'),
Text(733773,0,'1980-12-23 00:00:00'),
Text(735234,0,'1980-12-24 00:00:00'),
Text(736695,0,'1980-12-26 00:00:00')]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wBoNJ1D6-1633923375493)(output_194_1.png)]

y=AAPL_date['Adj Close'].values
x=AAPL_date.index
plt.plot(x,y)
[<matplotlib.lines.Line2D at 0x26a4cb87d68>]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nDQWorhL-1633923375499)(output_195_1.png)]

案例分析:美国各州人口数据分析

import numpy as np
import pandas as pd
from pandas import DataFrame
abb=pd.read_csv('../data/state-abbrevs.csv')
pop=pd.read_csv('../data/state-population.csv')
areas=pd.read_csv('../data/state-areas.csv')
display(abb.head(),pop.head(),areas.head())
stateabbreviation
0AlabamaAL
1AlaskaAK
2ArizonaAZ
3ArkansasAR
4CaliforniaCA
state/regionagesyearpopulation
0ALunder1820121117489.0
1ALtotal20124817528.0
2ALunder1820101130966.0
3ALtotal20104785570.0
4ALunder1820111125763.0
statearea (sq. mi)
0Alabama52423
1Alaska656425
2Arizona114006
3Arkansas53182
4California163707
# 合并pop与abbrevs两个DataFrame,分别依据state/region列和abbreviation列来合并。
# 为了保留所有信息,使用外合并。
pop_abb_df=pd.merge(left=pop,right=abb,left_on='state/region',right_on='abbreviation',how='outer')
pop_abb_df.head()
state/regionagesyearpopulationstateabbreviation
0ALunder1820121117489.0AlabamaAL
1ALtotal20124817528.0AlabamaAL
2ALunder1820101130966.0AlabamaAL
3ALtotal20104785570.0AlabamaAL
4ALunder1820111125763.0AlabamaAL
# 合并pop与abbrevs两个DataFrame,分别依据state/region列和abbreviation列来合并。
# 为了保留所有信息,使用外合并。
pop_abb_df2=pop.merge(abb,left_on='state/region',right_on='abbreviation',how='outer')
pop_abb_df2.head()
state/regionagesyearpopulationstateabbreviation
0ALunder1820121117489.0AlabamaAL
1ALtotal20124817528.0AlabamaAL
2ALunder1820101130966.0AlabamaAL
3ALtotal20104785570.0AlabamaAL
4ALunder1820111125763.0AlabamaAL

DataFrame.drop(labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors=‘raise’)

  • labels:待删除的行列名,labels = ‘A’ 即表示A列或者A行
  • axis:{0或1}默认方向为0,纵向也就是列方向,1则表示横向,即行方向
  • index:某一行或者多行
  • colums:某一列或者多列
  • level:等级,针对多重索引,暂时不会遇见
  • inplace:True 或 False 默认为false,指是否在原数据上做操作
  • errors:一般不会用到
# 去掉重复列abbreviation
drop_pop_abb_df=pop_abb_df.drop(labels='abbreviation',axis=1)
drop_pop_abb_df.head()
state/regionagesyearpopulationstate
0ALunder1820121117489.0Alabama
1ALtotal20124817528.0Alabama
2ALunder1820101130966.0Alabama
3ALtotal20104785570.0Alabama
4ALunder1820111125763.0Alabama
# 查看存在缺失数据的列。
# 使用.isnull().any(),只有某一列存在一个缺失数据,就会显示True。
drop_pop_abb_df.isnull().any(axis=0)
state/region
False
ages
False
year
False
population
True
state
True
dtype: bool
# 判断是否存在缺失值
drop_pop_abb_df.info()
# 可以看出,数据一共有2544条,但state列和population列数据量小于2544条,因此这两列中存在缺失数据。
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2544 entries, 0 to 2543
Data columns (total 5 columns):
state/region
2544 non-null object
ages
2544 non-null object
year
2544 non-null int64
population
2524 non-null float64
state
2448 non-null object
dtypes: float64(1), int64(1), object(3)
memory usage: 119.2+ KB
# 查看缺失数据
# 根据数据是否缺失情况显示数据,如果缺失为True,那么显示
# 使用.isnull().any(axis=1),只有某一行存在一个缺失数据,就会显示True
null_data=drop_pop_abb_df.loc[drop_pop_abb_df.isnull().any(axis=1)]
null_data.head()
state/regionagesyearpopulationstate
2448PRunder181990NaNNaN
2449PRtotal1990NaNNaN
2450PRtotal1991NaNNaN
2451PRunder181991NaNNaN
2452PRtotal1993NaNNaN
# 找到有哪些state/region使得state的值为NaN,使用unique()查看非重复值
null_data['state/region'].unique()
# 说明简称PR和USA没有对应的全称。
array(['PR', 'USA'], dtype=object)
# 为找到的这些state/region的state项补上正确的值
# 找到PR和USA的下标并将state的值改为Puerto Rico 和 United State 
pr_indexs = drop_pop_abb_df.loc[drop_pop_abb_df['state/region'] == 'PR'].index
drop_pop_abb_df.loc[pr_indexs, 'state'] = 'Puerto Rico'
usa_indexs = drop_pop_abb_df.loc[drop_pop_abb_df['state/region'] == 'USA'].index
drop_pop_abb_df.loc[usa_indexs, 'state'] = 'United State'
display(pr_indexs,usa_indexs)
Int64Index([2448, 2449, 2450, 2451, 2452, 2453, 2454, 2455, 2456, 2457, 2458,
2459, 2460, 2461, 2462, 2463, 2464, 2465, 2466, 2467, 2468, 2469,
2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477, 2478, 2479, 2480,
2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490, 2491,
2492, 2493, 2494, 2495],
dtype='int64')
Int64Index([2496, 2497, 2498, 2499, 2500, 2501, 2502, 2503, 2504, 2505, 2506,
2507, 2508, 2509, 2510, 2511, 2512, 2513, 2514, 2515, 2516, 2517,
2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2527, 2528,
2529, 2530, 2531, 2532, 2533, 2534, 2535, 2536, 2537, 2538, 2539,
2540, 2541, 2542, 2543],
dtype='int64')
drop_pop_abb_df.loc[2448]
state/region
PR
ages
under18
year
1990
population
NaN
state
Puerto Rico
Name: 2448, dtype: object
drop_pop_abb_df.loc[2496]
state/region
USA
ages
under18
year
1990
population
6.42185e+07
state
United State
Name: 2496, dtype: object
# 删除population列的缺失数据所在行
drop_pop_abb_df.loc[drop_pop_abb_df['population'].isnull()] # 行数据
index_nan=drop_pop_abb_df.loc[drop_pop_abb_df['population'].isnull()].index # 行下标
drop_pop_abb_df.drop(labels=index_nan,axis=0,inplace=True) # 删除行
drop_pop_abb_df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2524 entries, 0 to 2543
Data columns (total 5 columns):
state/region
2524 non-null object
ages
2524 non-null object
year
2524 non-null int64
population
2524 non-null float64
state
2524 non-null object
dtypes: float64(1), int64(1), object(3)
memory usage: 118.3+ KB
# 合并各州面积数据areas,使用左合并。
# 思考一下为什么使用左合并?因为要根据start关键字进行合并
total = pd.merge(areas,drop_pop_abb_df,how='left')
total.head()
statearea (sq. mi)state/regionagesyearpopulation
0Alabama52423ALunder1820121117489.0
1Alabama52423ALtotal20124817528.0
2Alabama52423ALunder1820101130966.0
3Alabama52423ALtotal20104785570.0
4Alabama52423ALunder1820111125763.0
# 再次查找缺省数据
total[total.isnull().any(axis=1)]
statearea (sq. mi)state/regionagesyearpopulation
total.loc[2448]
state
Puerto Rico
area (sq. mi)
3515
state/region
PR
ages
total
year
2000
population
3.81060e+06
Name: 2448, dtype: object
#找出2010年的全民人口数据,df.query(查询语句)
total_2010 = total.query("year==2010 & ages=='total'") # & and
| or
total_2010.head()
statearea (sq. mi)state/regionagesyearpopulation
3Alabama52423ALtotal20104785570.0
91Alaska656425AKtotal2010713868.0
101Arizona114006AZtotal20106408790.0
189Arkansas53182ARtotal20102922280.0
197California163707CAtotal201037333601.0
# 对查询结果进行处理,以state列作为新的行索引:set_index
state_total=total_2010.set_index("state")
state_total.head()
area (sq. mi)state/regionagesyearpopulation
state
Alabama52423ALtotal20104785570.0
Alaska656425AKtotal2010713868.0
Arizona114006AZtotal20106408790.0
Arkansas53182ARtotal20102922280.0
California163707CAtotal201037333601.0
# 计算人口密度。注意是Series/Series,其结果还是一个Series。
density = total_2010['population']/total_2010['area (sq. mi)']
density.head()
3
91.287603
91
1.087509
101
56.214497
189
54.948667
197
228.051342
dtype: float64
# 排序,并找出人口密度最高的五个州sort_values()
density.sort_values(ascending=False).head() # ascending=False 降序
ascending=True 升序
2405
8898.897059
2470
1058.665149
1397
1009.253268
1866
681.339159
293
645.600649
dtype: float64

要点总结:

  • 统一用loc()索引
  • 善于使用.isnull().any()找到存在NaN的列
  • 善于使用.unique()确定该列中哪些key是我们需要的
  • 一般使用外合并、左合并,目的只有一个:宁愿该列是NaN也不要丢弃其他列的信息

最后

以上就是单薄音响为你收集整理的Pandas练习(1-24题包含案例:苹果公司股票分析、美国各州人口分析)的全部内容,希望文章能够帮你解决Pandas练习(1-24题包含案例:苹果公司股票分析、美国各州人口分析)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部