Python Pandas使用

用于数据探索和分析,基于numpy模块

安装

pip install pandas

常用操作

Series

序列(可以理解为一列数据),举例:

>>> a = pandas.Series([2,1,6,3])
>>> pandas.Series([2,1,6,3])
0    2
1    1
2    6
3    3
dtype: int64

注:
上面没有指定索引,所以默认索引就为从0开始的数字,也可以自己指定索引,举例:

>>> pandas.Series([2,1,6,3], index=['a','b','c','d'])
a    2
b    1
c    6
d    3
dtype: int64
DataFrame

数据框(行列都有的数据),举例:

>>> a = pandas.DataFrame([[1,2,5,3],[3,6],[3,5,1,2,6]]) #里面不一定得数字
>>> a
   0  1    2    3    4
0  1  2  5.0  3.0  NaN
1  3  6  NaN  NaN  NaN
2  3  5  1.0  2.0  6.0
#最上面一行代表每一列序号,最左边一列代表每一行序号

注:
最后面有介绍DataFrame和Series的关系以及一些踩坑注意点

取值

按先列后行顺序取值,而且空的地方虽然为NaN,但是NaN之间是不等的,对上面的a举例:

>>> a[2][1]  #这里不是[1][2],是先列后行
nan
>>> a[3][1]
nan
>>> a[3][1] == a[3][1]
False  #可以看出两个NaN不等

注:
在pandas里异常的数据(如空)用NaN表示,以及无穷数用inf进行表示,此时对于NaN可以通过pandas下的isnull方法或者numpy下的isnan方法判断,而inf则通过numpy下的isinf判断,举例:

>>> a = pandas.DataFrame([[1,2,5,3],[3,6, float("inf")],[3,5,1,2,6]])
>>> a
   0  1         2    3    4
0  1  2  5.000000  3.0  NaN
1  3  6       inf  NaN  NaN
2  3  5  1.000000  2.0  6.0
>>> a.isnull()
       0      1      2      3      4
0  False  False  False  False   True
1  False  False  False   True   True
2  False  False  False  False  False
>>> np.isnan(a)
       0      1      2      3      4
0  False  False  False  False   True
1  False  False  False   True   True
2  False  False  False  False  False
>>> np.isinf(a)
       0      1      2      3      4
0  False  False  False  False  False
1  False  False   True  False  False
2  False  False  False  False  False
切片操作

使用iloc方法可以对DataFrame数据进行切片操作,使用切片操作时的顺序是先行后列,举例:

>>> a
   0  1    2    3    4
0  1  2  5.0  3.0  NaN
1  3  6  NaN  NaN  NaN
2  3  5  1.0  2.0  6.0
>>> a.iloc[2, 3:]
# 去第三行第四列以后的数据
3    2.0
4    6.0
Name: 2, dtype: float64

使用ix方法也可以进行切片操作,而且支持更加强大的筛选数据方式,如按列名筛选,举例:

>>> a = pandas.DataFrame([[1,2,5,3],[3,6],[3,5,1,2,6]])
>>> a.columns = ['a', 'b', 'c', 'd', 'e']
# 设置列名
>>> a
   a  b    c    d    e
0  1  2  5.0  3.0  NaN
1  3  6  NaN  NaN  NaN
2  3  5  1.0  2.0  6.0
>>> a.ix[:, a.columns == 'c']
# 索引所有行,且列名为c的那一列
     c
0  5.0
1  NaN
2  1.0
按条件筛选

举例:

>>> a = pandas.DataFrame([[1,2,5,3],[3,6],[3,5,1,2,6]])
>>> a
   0  1    2    3    4
0  1  2  5.0  3.0  NaN
1  3  6  NaN  NaN  NaN
2  3  5  1.0  2.0  6.0
>>> a[a[4].notnull()]
# 筛选第四列不为NaN的数据
   0  1    2    3    4
2  3  5  1.0  2.0  6.0
>>> a[a[1] > 2]
# 筛选第一列大于2的数据
   0  1    2    3    4
1  3  6  NaN  NaN  NaN
2  3  5  1.0  2.0  6.0
>>> a.T[a.T[0].notnull()].T
# 转置后筛选第0列不为NaN的数据,再转回来,即筛选第0行不为NaN的列
     0    1    2    3
0  1.0  2.0  5.0  3.0
1  3.0  6.0  NaN  NaN
2  3.0  5.0  1.0  2.0

注:
筛选后的数据不能够直接通过索引或者切片来进行某列的数据修改,因此需要使用到loc方法,要注意的是如果直接对索引后的数据进行赋值将会对整行的所有列都进行修改,举例:

>>> a = pandas.DataFrame([[1,2,5,3],[3,6],[3,5,1,2,6]])
>>> a
   0  1    2    3    4
0  1  2  5.0  3.0  NaN
1  3  6  NaN  NaN  NaN
2  3  5  1.0  2.0  6.0
>>> a[3] != 3.
# 筛选第三列不为3的数据
0    False
1     True
2     True
Name: 3, dtype: bool
>>> a[a[3] != 3.]
# 索引筛选后的数据
   0  1    2    3    4
1  3  6  NaN  NaN  NaN
2  3  5  1.0  2.0  6.0
>>> a.loc[a[3] != 3., 2] = 100.
# 修改筛选后数据的第三列为100.
>>> a
   0  1      2    3    4
0  1  2    5.0  3.0  NaN
1  3  6  100.0  NaN  NaN
2  3  5  100.0  2.0  6.0
>>> a[a[3] != 3.] = 200.
# 直接对筛选的数据赋值将会赋值到整行的所有数据
>>> a
# 可以看到2、3行全变成了200.
       0      1      2      3      4
0    1.0    2.0    5.0    3.0    NaN
1  200.0  200.0  200.0  200.0  200.0
2  200.0  200.0  200.0  200.0  200.0
列名定义

普通定义举例:

>>> b = pandas.DataFrame([[1,2,5,3],[3,6,'s'],[3,5,1,2,6]], columns=['one','two','three','four','five'])
>>> b
   one  two three  four  five
0    1    2     5   3.0   NaN
1    3    6     s   NaN   NaN
2    3    5     1   2.0   6.0
>>> b['one'][2]
3

字典定义举例,举例:

>>> pandas.DataFrame({"a":1,"b":[2,3],"c":'321'})
   a  b    c
0  1  2  321
1  1  3  321

可以看出a、c列里面因为只有一个元素,所以他们会自动重复复制补全。如果想要把某一列转成列表形式,可以用tolist(),举例:

>>> c = pandas.DataFrame([[1,2,5,3],[3,6],[3,5,1,2,6]]) #里面不一定得数字
>>> c[0].tolist()
[1, 3, 3]
>>> type(c[0].tolist())
<class 'list'>
转出格式

DataFrame数据可以直接输出成字典、CSV、excel等格式,举例:

c.to_list()                 #转列表
c.to_dict()                 #转成字典
c.to_csv("E:/a.csv")        #输出csv文件
c.to_excel("E:/abc.xlsx")   #输出excel文件
c.to_html("E:/abc.html")    #输出html文件
c.to_json("E:/abc.json")    #输出json
…
替换数据

使用replace方法可以将指定的一堆数据替换成其他数据,举例:

>>> a = pandas.DataFrame([[1,2,5,3],[3,6],[3,5,1,2,6]])
>>> a
   0  1    2    3    4
0  1  2  5.0  3.0  NaN
1  3  6  NaN  NaN  NaN
2  3  5  1.0  2.0  6.0
>>> a.replace([1., 3.], 100.)
# 将1和3都替换成100
     0  1      2      3    4
0  100  2    5.0  100.0  NaN
1  100  6    NaN    NaN  NaN
2  100  5  100.0    2.0  6.0
逐列操作

通过apply方法可以对数据进行逐列操作,举例:

>>> a = pandas.DataFrame([[1,2,5,3],[3,6],[3,5,1,2,6]])
>>> a
   0  1    2    3    4
0  1  2  5.0  3.0  NaN
1  3  6  NaN  NaN  NaN
2  3  5  1.0  2.0  6.0
>>> a.apply(lambda x: x+1)
# 对每列的数据都加1
   0  1    2    3    4
0  2  3  6.0  4.0  NaN
1  4  7  NaN  NaN  NaN
2  4  6  2.0  3.0  7.0

该方法默认是在维度为0的方向进行操作,即基于列操作,如果希望基于行操作,则可以设置属性axis=1

head()

头部数据,也就是前几行的,括号里写行数,不写默认显示前5行,如果要取后几行就用tail()

describe()

按列统计情况,举例:

>>> c = pandas.DataFrame([[1,2,5,3],[3,6,'s'],[3,5,1,2,6]], columns=['one','two','three','four','five'])
>>> c.describe()
            one       two      four  five
count  3.000000  3.000000  2.000000   1.0  #count说明这一列有几个元素
mean   2.333333  4.333333  2.500000   6.0  #这一列的平均数
std    1.154701  2.081666  0.707107   NaN  #标准差
min    1.000000  2.000000  2.000000   6.0  #最小值
25%    2.000000  3.500000  2.250000   6.0  #前%25分位数,和下面两行都是分位数
50%    3.000000  5.000000  2.500000   6.0
75%    3.000000  5.500000  2.750000   6.0
max    3.000000  6.000000  3.000000   6.0  #最大值

可以看出因为three那列有非数字内容存在,所以不会被统计

矩阵转置T

转置,就是行和列对调,举例:

>>> c = pandas.DataFrame({"a":1,"b":[2,3],"c":'321'})
>>> c
   a  b    c
0  1  2  321
1  1  3  321
>>> c.T
     0    1
a    1    1
b    2    3
c  321  321
导入文件
csv          read_csv()
excel        read_excel()
html         read_html()
txt          read_table()

例如:data = pandas.read_csv("a.csv"),像excel文件如果不想要表头(第一行)可以设置属性header=None,读取指定sheet可以设置sheetname属性,举例:

data = pandas.read_excel("a.xls", header=None, sheetname='test')

其中,html的特别厉害,他可以自动帮你获取一个网页里table标签的所有信息然后格式化打印出来,举例:

res = requests.get('https://wenku.baidu.com/list/202')  #这网页有嵌在表格里的内容
content = res.content.decode('gb2312')  #因为直接输出乱码,先转字节流再解码
c = pandas.read_html(content)
print(c)  #你会惊叹,虽然本质其实就是自动定位table标签的内容

注:
要使用read_excel()方法还需要:pip install xlrd

导入mysql数据

这块特殊讲,使用的是pymysql模块,可以参照前面,使用举例:

conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="123456", db="test")
cursor = conn.cursor()
sql = "select * from user"
k = pandas.read_sql(sql, conn)      #第一个参数查询语句、第二个是游标
print(k)
结果为:
  name password nickname
0    a        v        c
1  aaa      111   dawson
2  abc      aaa      abc
3  asd      sfa      fas
4   ch       ch       ch

注:
对于文件和mysql导入的数据,返回的类型是DataFrame,所以我们可以通过.shape来看有几行几列,通过.values来看其第几行第几列的对应信息,比如看第一行的就.value[0],第二行第一列就.value[1][0],还可以通过columns看有那些列,举例:

>>> c = pandas.DataFrame([[1,2,5,3],[3,6,'s'],[3,5,1,2,6]], columns=['one','two','three','four','five'])
>>> c
   one  two three  four  five
0    1    2     5   3.0   NaN
1    3    6     s   NaN   NaN
2    3    5     1   2.0   6.0
>>> c['one']
0    1
1    3
2    3
>>> c['one'][1]  #因为数据框必须先选列然后选行,所以不能只取某一行的数据
3
>>> c.values
array([[1, 2, 5, 3.0, nan],
       [3, 6, 's', nan, nan],
       [3, 5, 1, 2.0, 6.0]], dtype=object)
>>> c.values[0]  #values是先选行在选列,所以可以只取一行
array([1, 2, 5, 3.0, nan], dtype=object)
>>> c.values[0][3]  #values选列时是按0,1,2那样定位,不是按列名定位
3.0
>>> c.columns
Index(['one', 'two', 'three', 'four', 'five'], dtype='object')

甚至可以看、改变哪一列的哪个值的信息,比如对于上面数据库导入的信息:

k['name']

获得的就是name这一列的信息:

0       a
1     aaa
2     abc
3     asd
4      ch
Name: name, dtype: object

然后输入:

k['name'][k['name']=='asd']='ccc'
#将name这一列中值为asd的改为ccc,这里用k['name'][3]效果也一样
结果为:
0       a
1     aaa
2     abc
3     ccc
4      ch
Name: name, dtype: object
sort_values(by=哪一列)

根据某一列的值来排序,举例:

>>> c = pandas.DataFrame([[2,1,4,3],[1,4,6,2]])
>>> c
   0  1  2  3
0  2  1  4  3
1  1  4  6  2
>>> c.sort_values(by=0)
   0  1  2  3
1  1  4  6  2
0  2  1  4  3
data['列名'].unique()

计算某一列有多少种不同的元素,对上面的数据库数据举例:

>>> k['name'].unique()
array(['a', 'aaa', 'abc', 'ccc', 'ch'], dtype=object)
cut(数据, 份数[, labels=[每列名称]])

可以将数据分成好几份,会自动计算判断这块数据该处于哪份当中,举例:

>>> a = [0,2,3,93,4,5,70,16,48,76,25,30,31,50,51,100]
>>> c = pandas.cut(a, 4, labels=['低', '中', '高', '特高'])  #分成4份
>>> c
[低, 低, 低, 特高, 低, ..., 中, 中, 中, 高, 特高]
Length: 16
Categories (4, object): [低 < 中 < 高 < 特高]
>>> for each in c:
    print(each,end='\t')

低   低   低   特高  低   低   高   低   中   特高  低   中   中   中   高   特高  

上面的如果没有第三个参数,其就会按数值区间来区分,可以发现其是根据最大值和最小值来进行等宽处理,从而分块:

>>> pandas.cut(a, 4)
[(-0.1, 25.0], (-0.1, 25.0], (-0.1, 25.0], (75.0, 100.0], (-0.1, 25.0], ..., (25.0, 50.0], (25.0, 50.0], (25.0, 50.0], (50.0, 75.0], (75.0, 100.0]]
Length: 16
Categories (4, interval[float64]): [(-0.1, 25.0] < (25.0, 50.0] < (50.0, 75.0] < (75.0, 100.0]]
#能看出极差是100,所以每25分一块

如果不想按均分的范围来分块,我们可以自定义,此时只要第二个参数改成列表形式就行了,举例:

>>> pandas.cut(a, [0, 10, 50, 100]) #自定义分了3个区间
[NaN, (0, 10], (0, 10], (50, 100], (0, 10], ..., (10, 50], (10, 50], (10, 50], (50, 100], (50, 100]]
Length: 16
Categories (3, interval[int64]): [(0, 10] < (10, 50] < (50, 100]]
#因为0不在范围内,所以是NaN

此时如果想看分块情况可以用describe(),举例:

>>> b = pandas.cut(a, [0, 10, 50, 100]) #自定义分了3个区间
>>> b.describe()
            counts   freqs
categories                
(0, 10]          4  0.2500
(10, 50]         6  0.3750
(50, 100]        5  0.3125
NaN              1  0.0625

打印行数省略问题

pandas和numpy一样,当数据过多时,打印就会以省略号形式展示,此时可以通过set_option方法设置多少行以内的数据不以省略号进行展示,举例:

>>> pd.set_option('display.max_rows', 10)
# 超过10行就省略形式打印
>>> pd.DataFrame([[i] for i in range(100)])
     0
0    0
1    1
2    2
3    3
4    4
..  ..
95  95
96  96
97  97
98  98
99  99

[100 rows x 1 columns]
>>> pd.set_option('display.max_columns', 10)
# 超过10列就省略形式打印
>>> pd.DataFrame([[j for j in range(20)] for i in range(100)])
    0   1   2   3   4  ...  15  16  17  18  19
0    0   1   2   3   4 ...  15  16  17  18  19
1    0   1   2   3   4 ...  15  16  17  18  19
2    0   1   2   3   4 ...  15  16  17  18  19
3    0   1   2   3   4 ...  15  16  17  18  19
4    0   1   2   3   4 ...  15  16  17  18  19
..  ..  ..  ..  ..  .. ...  ..  ..  ..  ..  ..
95   0   1   2   3   4 ...  15  16  17  18  19
96   0   1   2   3   4 ...  15  16  17  18  19
97   0   1   2   3   4 ...  15  16  17  18  19
98   0   1   2   3   4 ...  15  16  17  18  19
99   0   1   2   3   4 ...  15  16  17  18  19

[100 rows x 20 columns]
>>> pd.set_option('display.max_rows', None)
# 不管多少行都不省略打印

DataFrame和Series关系以及使用注意(小心踩坑)

关系

在pandas中,这两者的关系可以理解成:DataFrame是Series的集合,DataFrame中的每一行或者每一列都可以看做是一个Series。如何区分DataFrame和Series呢,在打印的时候就可以看出来,例如下面:

>>> a = pd.DataFrame([[j for j in range(10)] for i in range(100)])
>>> a
    0  1  2  3  4  5  6  7  8  9
0   0  1  2  3  4  5  6  7  8  9
1   0  1  2  3  4  5  6  7  8  9
2   0  1  2  3  4  5  6  7  8  9
3   0  1  2  3  4  5  6  7  8  9
4   0  1  2  3  4  5  6  7  8  9
.. .. .. .. .. .. .. .. .. .. ..
95  0  1  2  3  4  5  6  7  8  9
96  0  1  2  3  4  5  6  7  8  9
97  0  1  2  3  4  5  6  7  8  9
98  0  1  2  3  4  5  6  7  8  9
99  0  1  2  3  4  5  6  7  8  9

[100 rows x 10 columns]
>>> type(a)
# a是个DataFrame
<class 'pandas.core.frame.DataFrame'>
>>> a[0]
# 取a的第一列
0     0
1     0
2     0
3     0
4     0
     ..
95    0
96    0
97    0
98    0
99    0
Name: 0, Length: 100, dtype: int64
>>> type(a[0])
# 可以看到第一列是个Series
<class 'pandas.core.series.Series'>
>>> a.iloc[0, :]
# 取a的第一行
0    0
1    1
2    2
3    3
4    4
5    5
6    6
7    7
8    8
9    9
Name: 0, dtype: int64
>>> type(a.iloc[0, :])
# 可以看到第一行也是个Series
<class 'pandas.core.series.Series'>

上面代码证明了每一行每一列都是Series,然后多个Series组成了DataFrame,而且打印的时候也可以看出:DataFrame的打印结果里面有多行多列,而且一般会有像[100 rows x 10 columns]这样的行列数提示;而Series的打印中一般会显示像Name: 0, Length: 100, dtype: int64这样的Name以及数据类型的提示等

注意

为什么这里要介绍两者的关系呢?因为这里面可能有个坑需要注意,假如我们想把两个DataFrame的某些列合并起来,将可能遇到一些坑,这里介绍两种方式实现,以及对应可能有的坑:

1. 通过zip映射合并

(一般推荐使用第二种方式合并,只是使用zip的方式有个比较明显的坑,所以先举例),举例:

>>> a = pd.DataFrame([[j for j in range(10)] for i in range(100)])
# 定义a和b两个DataFrame
>>> b = pd.DataFrame([[j*10 for j in range(10)] for i in range(100)])
>>> pd.DataFrame(list(zip(a.iloc[:, [1, 2]], b[0])))
# 将a的2/3列与b的第一列合并,发现结果竟然是这个?
   0  1
0  1  0
1  2  0
>>> pd.DataFrame(list(zip(a.iloc[:, 1], b[0])))
# 再看合并a的第二列和b的第一列是没问题的
    0  1
0   1  0
1   1  0
2   1  0
3   1  0
4   1  0
.. .. ..
95  1  0
96  1  0
97  1  0
98  1  0
99  1  0

[100 rows x 2 columns]

可以看出上面将多列和单列合并失败,竟然只有几行?究其原因,最后发现是DataFrame和Series是不同类型的,因此通过zip不能直接合并(后来尝试了以后证明:DataFrame之间也不能这样直接合并),所以要合并的时候需要通过Series来合并,例如上面的代码就要修改成:

>>> pd.DataFrame(list(zip(a[1], a[2], b[0])))
# 分成3个Series来合并
    0  1  2
0   1  2  0
1   1  2  0
2   1  2  0
3   1  2  0
4   1  2  0
.. .. .. ..
95  1  2  0
96  1  2  0
97  1  2  0
98  1  2  0
99  1  2  0

[100 rows x 3 columns]

可以看到结果就没问题了

2. 通过pandas下的concat方法合并

举例:

>>> a = pd.DataFrame([[j for j in range(10)] for i in range(100)])
# 定义a和b两个DataFrame
>>> b = pd.DataFrame([[j*10 for j in range(10)] for i in range(100)])
>>> pd.concat([a.iloc[:, [1,2]], b[0]], axis=1)
# 在列的那一维度进行合并,可以看到结果没问题
    1  2  0
0   1  2  0
1   1  2  0
2   1  2  0
3   1  2  0
4   1  2  0
.. .. .. ..
95  1  2  0
96  1  2  0
97  1  2  0
98  1  2  0
99  1  2  0

[100 rows x 3 columns]

这种方法是比较推荐的,一般来说使用都没问题。但有种情况下得谨慎使用:索引不匹配的时候。比如你在a中筛选了几行,然后和b中的其他几行进行合并,假如此时在a中你筛选出了所有的单数行,然后和b中的所有偶数行合并,那么可能就会出现如下情况:

>>> a_ = a.iloc[[i for i in range(1, 100, 2)], 0]
# 取a的所有奇数行
>>> a_
1     0
3     0
5     0
7     0
9     0
     ..
91    0
93    0
95    0
97    0
99    0
Name: 0, Length: 50, dtype: int64
>>> b_ = b.iloc[[i for i in range(0, 100, 2)], 0]
# 取b的所有偶数行
>>> b_
0     0
2     0
4     0
6     0
8     0
     ..
90    0
92    0
94    0
96    0
98    0
Name: 0, Length: 50, dtype: int64
>>> pd.concat([a_, b_], axis=1)
# 将两列合并
      0    0
0   NaN  0.0
1   0.0  NaN
2   NaN  0.0
3   0.0  NaN
4   NaN  0.0
..  ...  ...
95  0.0  NaN
96  NaN  0.0
97  0.0  NaN
98  NaN  0.0
99  0.0  NaN

[100 rows x 2 columns]

可以看到合并后的结果有问题,竟然有一对NaN!究其原因,是因为两组合并的数据索引不同,所以相当于重新建立一个1到100的索引,然后两列对号入座,第一列就只有奇数行有数字,第二列只有偶数行有数字。所以如果我们只是想单纯的合并这两列的话,就需要把索引能够对上号,因此可以使用reset_index方法重置索引后再合并,举例:

>>> a_
1     0
3     0
5     0
7     0
9     0
     ..
91    0
93    0
95    0
97    0
99    0
Name: 0, Length: 50, dtype: int64
>>> a_.reset_index()
# 重置索引,可以看到索引被重置成0到49了,并且还新建了一个`index`列来保留原来的索引
    index  0
0       1  0
1       3  0
2       5  0
3       7  0
4       9  0
..    ... ..
45     91  0
46     93  0
47     95  0
48     97  0
49     99  0

[50 rows x 2 columns]
>>> a_.reset_index()[0]
# 这里我们不需要原来的索引,所以直接取第0列就可以了
0     0
1     0
2     0
3     0
4     0
     ..
45    0
46    0
47    0
48    0
49    0
Name: 0, Length: 50, dtype: int64
>>> pd.concat([a_.reset_index()[0], b_.reset_index()[0]], axis=1)
# 重置索引后合并,可以发现没问题了
    0  0
0   0  0
1   0  0
2   0  0
3   0  0
4   0  0
.. .. ..
45  0  0
46  0  0
47  0  0
48  0  0
49  0  0

[50 rows x 2 columns]

然后我们尝试下用zip方式合并索引没对上号的两列有没有问题:

>>> pd.DataFrame(list(zip(a_, b_)))
    0  1
0   0  0
1   0  0
2   0  0
3   0  0
4   0  0
.. .. ..
45  0  0
46  0  0
47  0  0
48  0  0
49  0  0

[50 rows x 2 columns]

可以看到结果是没问题的,因为zip只是对两列数据建立映射关系,并不关心索引。
由此可以得出结论:这两种方法的坑是互补的...哦不对...这两种方式使用时都有不同的坑,使用时务必要小心!

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

推荐阅读更多精彩内容