数据分析-2 numpy

摘要

  1. 什么是numpy
  2. numpy基础
  3. numpy常用方法
  4. numpy常用统计方法
    为什么要学习numpy:1. 快速;2. 方便;3. 科学计算的基础库

numpy是一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算

1. 使用numpy生成数组,得到ndarray

NumPy的核心特征之一就是N维数组对象ndarry。ndarry是Python中一个快速、灵活的大型数据集容器。数组允许使用类似于标量的操作语法在整块数据上进行数学计算。
一个ndarry是一个通用的多维同类数据容器,也就是说它包含的每一个元素均为相同类型。每一个数组都有一个shape属性,用来表征数组每一维度的数量; 每一个数组都有一个dtype属性,用来描述数组的数据特征。

  • 创建ndarray的3种方法
import numpy as np
#方法1
t1=np.array([1,2,3]) #传入列表
print(t1)
print(type(t1))
#[1 2 3]
# <class 'numpy.ndarray'>

#方法2
t2=np.array(range(10)) #传入range生成的可迭代对象
print(t2)
print(type(t2))
# [0 1 2 3 4 5 6 7 8 9]
# <class 'numpy.ndarray'>

#方法3 和2原理一样
t3=np.arange(4,10,2) ##np.arange()等同于np.array(range()) 
print(t3)
print(type(t3))
# [4 6 8]
# <class 'numpy.ndarray'>
  • 数组类型(dtype)的操作
print(t3.dtype)
#int64
t4=t3.astype(np.int8) #修改数组的数据类型
print(t4.dtype)
#int8
t5=np.array(range(1,4),dtype='float') #指定创建数组的数据类型
print(t5)
print(t5.dtype)
# [1. 2. 3.]
# float64

import random
t6=np.array([random.random() for i in range(10)]) #random.random()用于生成一个0到1的随机符点数: 0 <= n < 1.0
print(t6)
print(t6.dtype)
# [0.2530124  0.19825549 0.61507    0.36285379 0.9481657  0.67246082
#  0.80597906 0.24741171 0.73392225 0.97530711]
# float64
t7=np.round(t5,2) #修改浮点型的小数位数
print(t)
print(t7.dtype)
# [0.58 0.27 0.22 0.2  0.23 0.94 0.64 0.77 0.81 0.54]
# float64

python中常见的更多数据类型

  • 数组的形状
import numpy as np
t1=np.arange(12)
print(t1)
print(t1.shape)
# [ 0  1  2  3  4  5  6  7  8  9 10 11]
# (12,)
t2=np.array([[1,2,3],[4,5,6]])
print(t2)
print(t2.shape)
# [[1 2 3]
#  [4 5 6]]
# (2, 3)
t3=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
print(t3)
print(t3.shape)
# [[[ 1  2  3]
#   [ 4  5  6]]

#  [[ 7  8  9]
#   [10 11 12]]]
# (2, 2, 3)

修改数组的形状

⚠️ reshape方法是有返回值return的,其本身没有发生变化
t1.reshape((3,4))  #传入元组
print(t1.reshape((3,4)))
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]
print(t1)
print(t1.shape)
# [ 0  1  2  3  4  5  6  7  8  9 10 11]
# (12,)
 
#需要用新的变量来接收
t4=t1.reshape((3,4))
print(t4)
print(t4.shape)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]
# (3, 4)
t5=np.arange(24).reshape((2,3,4))
print(t5)
print(t5.shape)
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]
# (2, 3, 4)

t6=np.arange(4)  #注意t6 t7和t8的区别
print(t6)
print(t6.shape)
# [0 1 2 3]
# (4,)
t7=t6.reshape((4,1))
print(t7)
print(t7.shape)
# [[0]
#  [1]
#  [2]
#  [3]]
# (4, 1)
t8=t6.reshape((1,4))
print(t8)
print(t8.shape)
# [[0 1 2 3]]
# (1, 4)

t9=t4.reshape((t4.shape[0]*t4.shape[1],))  #在不知道有多少个值存在的情况下二维转一维。shape[0]是行数,shape[1]是列数。
print(t9)
print(t9.shape)
# [ 0  1  2  3  4  5  6  7  8  9 10 11]
# (12,)
t10=t4.flatten() #flatten可以直接二维转一维
print(t10)
print(t10.shape)
# [ 0  1  2  3  4  5  6  7  8  9 10 11]
# (12,)

2. 数组的计算

数组和数的计算:
numpy具有广播机制,在运算过程中,加减乘除的值被光波到所有元素上面

import numpy as np
t1=np.arange(12)
print(t1)
# [ 0  1  2  3  4  5  6  7  8  9 10 11]
print(t1+1)
# [ 1  2  3  4  5  6  7  8  9 10 11 12]
print(t1*3)
# [ 0  3  6  9 12 15 18 21 24 27 30 33]

维度相同的数组和数组的计算:

t2=t1+10
print(t2)
# [10 11 12 13 14 15 16 17 18 19 20 21]
t3=t1*t2
print(t3)
# [  0  11  24  39  56  75  96 119 144 171 200 231]

维度不同的数组和数组的计算:
⚠️广播原则:
如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符或者其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。
维度可以理解为shape所对应的数字个数

t4=np.arange(4).reshape(4,1)
print(t4)
# [[0]
#  [1]
#  [2]
#  [3]]
t5=np.arange(24).reshape((2,4,3))
print(t5)
# [[[ 0  1  2]
#   [ 3  4  5]
#   [ 6  7  8]
#   [ 9 10 11]]
#
#  [[12 13 14]
#   [15 16 17]
#   [18 19 20]
#   [21 22 23]]]
t6=t5-t4
print(t6)
# [[[ 0  1  2]
#   [ 2  3  4]
#   [ 4  5  6]
#   [ 6  7  8]]
#
#  [[12 13 14]
#   [14 15 16]
#   [16 17 18]
#   [18 19 20]]]

轴的概念:
在numpy中可以理解为方向,使用0,1,2...数字表示,对于一个一维数组,只有一个0轴,对于2维数组(shape(2,2)),有0轴和1轴,对于三维数组(shape(2,2, 3)),有0,1,2轴
有了轴的概念之后,我们计算会更加方便,比如计算一个2维数组的平均值,必须指定是计算哪个方向上面的数字的平均值
回顾np.arange(0,10).reshape((2,5)),reshpe中2表示0轴长度(包含数据的条数)为2,1轴长度为5,2X5一共10个数据

二维数组axis=0表示作用于行,axis=1表示作用于列
x.shape[0]是取行 (方括号里的内容),x.shape[1]是取列 (方括号间对应部分的内容) 。

3. numpy读取本地数据和切片索引操作

pandas比numpy读取数据功能更强大,所以numpy读取数据功能只需简单了解即可

  • 读取:
    语法:
    np.loadtxt(frame,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)
    (loadtxt并不是说只能从txt读取文件,而是读取文本文件)
参数 解释
frame 文件、字符串或产生器(文件路径),可以是.gz或bz2压缩文件
dtype 数据类型,csv的字符串以什么数据类型读入数组中。默认是np.float,默认情况下对于较大的数据会将其变为科学计数的方式
delimiter 分隔字符串,默认是任何空格。读取csv是设置为","
skiprows 跳过前x行,一般跳过第一行表头
usecols 读取指定的列,索引,元组类型
unpack 默认为False。如果为True,读入属性将分别写入不同的数组变量,False读入数据只写入一个数组变量。(即:转置)
import numpy as np
us_file_path='../youtube_video_data/US_video_data_numbers.csv'
#如果不设置delimiter会报错,如果不设置dtype出来的数字是科学计数法的形式
t1=np.loadtxt(us_file_path,delimiter=",",dtype='int')
t2=np.loadtxt(us_file_path,delimiter=",",dtype='int',unpack=True) #unpack=True,发生了行和列的转置
print(t1)
print('*'*100)
print(t2)
# [[4394029  320053    5931   46245]
#  [7860119  185853   26679       0]
#  [5845909  576597   39774  170708]
#  ...
#  [ 142463    4231     148     279]
#  [2162240   41032    1384    4737]
#  [ 515000   34727     195    4722]]
# ****************************************************************************************************
# [[4394029 7860119 5845909 ...  142463 2162240  515000]
#  [ 320053  185853  576597 ...    4231   41032   34727]
#  [   5931   26679   39774 ...     148    1384     195]
#  [  46245       0  170708 ...     279    4737    4722]]

练习题:
英国和美国各自youtube1000的数据结合之前的matplotlib绘制出各自的评论数量的直方图
希望了解英国的youtube中视频的评论数和喜欢数的关系,应该如何绘制改图

import numpy as np
from matplotlib import pyplot as plt
#第1题
us_file_path='../youtube_video_data的副本/US_video_data_numbers.csv'
t_us=np.loadtxt(us_file_path,delimiter=",",dtype='int')
# 选取评论的数据
t_us_comments=t_us[:,-1] #-1是取最后一行
t_us_comments=t_us_comments[t_us_comments<=5000] #有极值,所以只取小于5000的值
#绘制直方图
print(t_us_comments.max(),t_us_comments.min())
#582505 0
d=100
bin_nums=(t_us_comments.max()-t_us_comments.min())//d
#绘图
plt.figure(figsize=(20,8),dpi=300)
plt.hist(t_us_comments,bin_nums)
plt.show()

#第2题
uk_file_path='../youtube_video_data的副本/GB_video_data_numbers.csv'
t_uk=np.loadtxt(uk_file_path,delimiter=",",dtype='int')
#选择喜欢数比50万小的数据
t_uk=t_uk[t_uk[:,1]<=500000]
t_uk_comments=t_uk[:,-1]
t_uk_likes=t_uk[:,1]
plt.figure(figsize=(20,8),dpi=300)
plt.scatter(t_uk_likes,t_uk_comments)
plt.show()
  • 二维数组转置的三种方式:transpose, Tswapaxes
    转置是一种变换,对于numpy中的数组来说,就是在对角线方向交换数据,目的也是为了更方便的去处理数据
import numpy as np
t1=np.arange(24).reshape((4,6))
print(t1)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]
print(t1.transpose())
# [[ 0  6 12 18]
#  [ 1  7 13 19]
#  [ 2  8 14 20]
#  [ 3  9 15 21]
#  [ 4 10 16 22]
#  [ 5 11 17 23]]
print(t1.T)
# [[ 0  6 12 18]
#  [ 1  7 13 19]
#  [ 2  8 14 20]
#  [ 3  9 15 21]
#  [ 4 10 16 22]
#  [ 5 11 17 23]]
print(t1.swapaxes(1,0))
# [[ 0  6 12 18]
#  [ 1  7 13 19]
#  [ 2  8 14 20]
#  [ 3  9 15 21]
#  [ 4 10 16 22]
#  [ 5 11 17 23]]
  • ⚠️numpy索引和切片
import numpy as np
us_file_path='../youtube_video_data的副本/US_video_data_numbers.csv'
t1=np.loadtxt(us_file_path,delimiter=",",dtype='int')

print(t1)
#取单行
print(t1[2])#取第三行
print(t1[2,:]) #和上一行作用相同。逗号前表示行,逗号后表示列。冒号表示所有列都要
#取连续的多行
print(t1[2:]) #取3到最后一行
print(t1[2:,:])
#取不连续的多行
print(t1[[2,8,10]]) #取3,9,11行
print(t1[[2,8,10],:])

#取单列
print(t1[:,0]) #第一列
#取连续的多列
print(t1[:,2:]) #取3到最后一列
#取不连续的多列
print(t1[:,[2,8,10]]) #取3,9,11列

#取多行多列 (取行和列交叉点的位置)
print(t1[2,3]) #取3行4列
print(t1[2:5,1:4]) #取3到5行,2到4列
#取多个不相邻的点(前面方括号里的行和后面方括号里的列一一对应)
print(t1[[0,2,2],[0,1,3]]) #取坐标为(0,0)(2,1)(2,3)的这三个点
  • numpy中数值的修改(赋值)
  1. 修改单个值的话,直接用索引找到那个值再用=赋值即可
  2. 批量修改--采用布尔索引
import numpy as np
t=np.arange(24).reshape(4,6)
print(t)
#把t中小于0的数字替换为3
print(t<10)
#[[ True  True  True  True  True  True]
# [ True  True  True  True False False]
# [False False False False False False]
# [False False False False False False]]
t[t<10]=3
print(t)
# [[ 3  3  3  3  3  3]
#  [ 3  3  3  3 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]
  1. 批量修改--python中的三元运算符 np.where(判断式,T时返回的值,F时返回的值)
import numpy as np
t=np.arange(24).reshape(4,6)
print(t)
#将小于等于3的替换成100,否则替换成300
t1=np.where(t<=3,100,300)  #np.where没有返回值,需要用变量接收
print(t1)
# [[100 100 100 100 300 300]
#  [300 300 300 300 300 300]
#  [300 300 300 300 300 300]
#  [300 300 300 300 300 300]]
  1. clip(裁剪)操作
    可用于去除极值
import numpy as np
t=np.arange(24).reshape(4,6)
print(t)
#将小于等于10的替换成10,大于10的替换成18
t1=t.clip(10,18)  
print(t1)
# [[10 10 10 10 10 10]
#  [10 10 10 10 10 11]
#  [12 13 14 15 16 17]
#  [18 18 18 18 18 18]]

4. numpy中的nan和常用方法以及inf

nan(NAN,Nan):not a number表示不是一个数字
当我们读取本地的文件为float的时候,如果有缺失,就会出现nan
当做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大)也会出现nan

inf(-inf,inf):infinity,inf表示正无穷,-inf表示负无穷
什么时候回出现inf包括(-inf,+inf)
比如一个数字除以0,(python中直接会报错,numpy中是一个inf或者-inf)

  • nan的注意点:
  1. nan和inf都是浮点型⚠️
import numpy as np
a=np.nan
print(type(a))
# <class 'float'>
b=np.inf
print(type(b))
# <class 'float'>
  1. 两个nan是不相等的
import numpy as np
print(np.nan==np.nan)
# False
print(np.nan!=np.nan)
#True
  1. 可以使用np.isnan()来判断一个数字是不是nan
import numpy as np
t1=np.arange(15,dtype=float).reshape(3,5)
t1[2,2]=np.nan
print(t1)
# [[ 0.  1.  2.  3.  4.]
#  [ 5.  6.  7.  8.  9.]
#  [10. 11. nan 13. 14.]]
print(np.isnan(t1))
# [[False False False False False]
#  [False False False False False]
#  [False False  True False False]]
  1. 利用2和3的特点,使用 np.count_nonzero来统计数组中nan的个数
import numpy as np
t1=np.arange(15,dtype=float).reshape(3,5)
t1[2,2]=np.nan
print(t1)
# [[ 0.  1.  2.  3.  4.]
#  [ 5.  6.  7.  8.  9.]
#  [10. 11. nan 13. 14.]]
print(np.count_nonzero(t1!=t1)) #只有nan才不等于它本身
#1
print(np.count_nonzero(np.isnan(t1)))
#1
  1. nan和任何值计算都是nan
import numpy as np
t1=np.arange(15,dtype=float).reshape(3,5)
t1[2,2]=np.nan
print(np.sum(t1))
# nan
print(t1)
# [[ 0.  1.  2.  3.  4.]
#  [ 5.  6.  7.  8.  9.]
#  [10. 11. nan 13. 14.]]
print(np.sum(t1,axis=0))
#[15. 18. nan 24. 27.]
  • numpy中常用统计函数
    思考:在一组数据中单纯的把nan替换为0会带来什么样的影响?
    全部替换为0后,替换之前的平均值如果大于0,替换之后的均值肯定会变小,所以更一般的方式是把缺失的数值替换为均值(中值)或者是直接删除有缺失值的一行

将nan替换成列的均值:

import numpy as np
t1=np.arange(12,dtype=float).reshape(3,4)
t1[1,2:]=np.nan
print(t1)
# [[ 0.  1.  2.  3.]
#  [ 4.  5. nan nan]
#  [ 8.  9. 10. 11.]]
# [12. 15. nan nan]
def fill_ndarray(t1):
    for i in range(t1.shape[1]): #遍历每一列
        temp_col = t1[:,i] #当前的一列
        nan_num=np.count_nonzero(temp_col!=temp_col)
        if nan_num !=0:
            temp_not_nan_col=temp_col[temp_col==temp_col] #当前这一列不为n的array
            temp_col[np.isnan(temp_col)]=temp_not_nan_col.mean() #选中当前为nan的位置,把值赋值为不为nan的均值
            pass
    return t1
t2=fill_ndarray(t1)
print(t2)
# [[ 0.  1.  2.  3.]
#  [ 4.  5.  6.  7.]
#  [ 8.  9. 10. 11.]]

pandas有更容易的方法处理缺失值

5. 数组的拼接和行列交换

  • 竖直拼接和水平拼接:
import numpy as np
t1=np.arange(12).reshape(2,6)
print(t1)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]]
t2=np.arange(12,24).reshape(2,6)
print(t2)
# [[12 13 14 15 16 17]
#  [18 19 20 21 22 23]]
t3=np.vstack((t1,t2))  #竖直拼接vertically
print(t3)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]
t4=np.hstack((t1,t2))  #水平拼接horizontally
print(t4)
# [[ 0  1  2  3  4  5 12 13 14 15 16 17]
#  [ 6  7  8  9 10 11 18 19 20 21 22 23]]

竖直切割和水平切割是竖直拼接和水平拼接的逆操作

  • 行列交换
    数组水平或者竖直拼接之前应该注意:
    竖直拼接的时候:每一列代表的意义相同!!!否则牛头不对马嘴。如果每一列的意义不同,这个时候应该交换某一组的数的列,让其和另外一类相同。水平拼接时也是一样
import numpy as np
t1=np.arange(12,24).reshape(3,4)
print(t1)
# [[12 13 14 15]
#  [16 17 18 19]
#  [20 21 22 23]]
t1[[1,2],:]=t1[[2,1],:] #行交换(第2行和第3行交换)
print(t1)
# [[12 13 14 15]
#  [20 21 22 23]
#  [16 17 18 19]]
t1[:,[0,2]]=t1[:,[2,0]] #列交换(第1行和第3行交换)
print(t1)
# [[14 13 12 15]
#  [22 21 20 23]
#  [18 17 16 19]]

练习:把之前案例中两个国家的数据方法一起来研究分析,同时保留国家的信息(每条数据的国家来源)。

import numpy as np
#加载国家数据
us_file_path='../youtube_video_data的副本/US_video_data_numbers.csv'
us_data=np.loadtxt(us_file_path,delimiter=",",dtype='int')
uk_file_path='../youtube_video_data的副本/GB_video_data_numbers.csv'
uk_data=np.loadtxt(uk_file_path,delimiter=",",dtype='int')
#添加 国家信息(用0和1来代表)
zero_data=np.zeros((us_data.shape[0],1)).astype(int)
ones_data=np.ones((uk_data.shape[0],1)).astype(int)
us_data=np.hstack((us_data,zero_data))
uk_data=np.hstack((uk_data,ones_data))
#拼接两组数据
final_data=np.vstack((us_data,uk_data))
print(final_data)
# [[4394029  320053    5931   46245       0]
#  [7860119  185853   26679       0       0]
#  [5845909  576597   39774  170708       0]
#  ...
#  [ 109222    4840      35     212       1]
#  [ 626223   22962     532    1559       1]
#  [  99228    1699      23     135       1]]
  • numpy更多好用的方法
    1.获取最大值最小值的位置
    np.argmax(t,axis=0)
    np.argmin(t,axis=1)
    2.创建一个全0的数组: np.zeros((3,4))
    3.创建一个全1的数组:np.ones((3,4))
    4.创建一个对角线为1的正方形数组(方阵):np.eye(3)
    5.numpy生成随机数
  • numpy的注意点copy和view
    a=b 完全不复制,a和b相互影响
    a = b[:],视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,他们两个的数据变化是一致的,
    a = b.copy(),复制,a和b互不影响

6. 小结

  1. 如何选择一行或者多行的数据(列)?
  2. 如何给选取的行或者列赋值?
  3. 如何把大于10的值替换为10?
  4. np.where如何使用?
  5. np.clip如何使用?
  6. 如何转置(交换轴)?
  7. 读取和保存数据为csv
  8. np.nan和np.inf是什么
  9. 常用的统计函数你记得几个?
  10. 标准差反映出数据的什么信息?

参考:https://www.runoob.com/numpy/numpy-array-from-existing-data.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容