【Chapter 8.2】合并数据集

【Chapter 8.2】合并数据集

pandas里有几种方法可以合并数据:

  1. pandas.merge 按一个或多个key把DataFrame中的行连接起来。这个和SQL或其他一些关系型数据库中的join操作相似。
  2. pandas.concat 在一个axis(轴)上,串联或堆叠(stack)多个对象。
  3. combine_first 实例方法(instance method)能合并相互之间有重复的数据,并用一个对象里的值填满缺失值

这里每一个都会给出一些例子。这些用法贯穿这本书。

1 数据库风格的DataFrame Joins

Merge或join操作,能通过一个或多个key,把不同的数据集的行连接在一起。这种操作主要集中于关系型数据库。pandas中的merge函数是这种操作的主要切入点:

df2 = pd.DataFrame({'key': ['a', 'b', 'd'],
                    'data2': range(3)})
df2
                    
Out[575]: 
   data2 key
0      0   a
1      1   b
2      2   d
df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                    'data1': range(7)})

df1

Out[577]: 
   data1 key
0      0   b
1      1   b
2      2   a
3      3   c
4      4   a
5      5   a
6      6   b

这个例子是many-to-one join(多个变为一个的连接);在df1中有标签为a和b的行,而df2中的key列,每一行只有对应的一个值。调用merge我们可以得到:

pd.merge(df1, df2)#没有指定连接键,默认用重叠列名,没有指定连接方式  
Out[576]: 
   data1 key  data2
0      0   b      1
1      1   b      1
2      6   b      1
3      2   a      0
4      4   a      0
5      5   a      0

这里我们并没有指定按哪一列来连接。如果我们没有指定,merge会用两个对象中都存在的列名作为key(键)。当然,最好还是清楚指定比较好:

pd.merge(df1, df2, on='key')
Out[578]: 
   data1 key  data2
0      0   b      1
1      1   b      1
2      6   b      1
3      2   a      0
4      4   a      0
5      5   a      0

如果每一个对象中的列名不一会,我们可以分别指定:

df3 = pd.DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 
                             'data1': range(7)})

df4 = pd.DataFrame({'rkey': ['a', 'b', 'd'], 
                             'data2': range(3)})
                             
df3
Out[582]: 
   data1 lkey
0      0    b
1      1    b
2      2    a
3      3    c
4      4    a
5      5    a
6      6    b

df4
Out[583]: 
   data2 rkey
0      0    a
1      1    b
2      2    d

pd.merge(df3, df4, left_on='lkey', right_on='rkey')
pd.merge(df3, df4, left_on='lkey', right_on='rkey')
Out[584]: 
   data1 lkey  data2 rkey
0      0    b      1    b
1      1    b      1    b
2      6    b      1    b
3      2    a      0    a
4      4    a      0    a
5      5    a      0    a

我们可能注意到,在结果中并没有c和d。因为merge默认是inner join(内连接),结果中的key是交集的结果,或者在两个表格中都有的集合。其他一些可选项,比如left, right, outer。outer join(外连接)取key的合集,其实就是left join和right join同时应用的效果:

pd.merge(df1, df2, how='outer')
Out[585]: 
   data1 key  data2
0    0.0   b    1.0
1    1.0   b    1.0
2    6.0   b    1.0
3    2.0   a    0.0
4    4.0   a    0.0
5    5.0   a    0.0
6    3.0   c    NaN
7    NaN   d    2.0

多对多的合并有些不直观。看下面的例子:


df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'], 
                    'data1': range(6)})

df1

Out[586]: 
   data1 key
0      0   b
1      1   b
2      2   a
3      3   c
4      4   a
5      5   b

df2 = pd.DataFrame({'key': ['a', 'b', 'a', 'b', 'd'], 
                    'data2': range(5)})
df2
                    
Out[587]: 
   data2 key
0      0   a
1      1   b
2      2   a
3      3   b
4      4   d
pd.merge(df1, df2, on='key', how='left')
Out[588]: 
    data1 key  data2
0       0   b    1.0
1       0   b    3.0
2       1   b    1.0
3       1   b    3.0
4       2   a    0.0
..    ...  ..    ...
6       3   c    NaN
7       4   a    0.0
8       4   a    2.0
9       5   b    1.0
10      5   b    3.0

[11 rows x 3 columns]

many-to-many join是对行进行笛卡尔集运算。(两个集合X和Y的笛卡儿积(Cartesian product),又称直积,在集合论中表示为X × Y,是所有可能的有序对组成的集合。比如1到13是一个集合,四种花色是一个集合,二者的笛卡尔积就有52个元素)。这里在左侧的DataFrame中有三行含b,右边的DataFrame则有两行含b,于是结果是有六行含b。这个join方法只会让不相同的key值出现在最后的结果里:

pd.merge(df1, df2, how='inner')
Out[589]: 
   data1 key  data2
0      0   b      1
1      0   b      3
2      1   b      1
3      1   b      3
4      5   b      1
5      5   b      3
6      2   a      0
7      2   a      2
8      4   a      0
9      4   a      2

用多个key来连接的话,用一个含有多个列名的list来指定:


left = pd.DataFrame({'key1': ['foo', 'foo', 'bar'], 
                     'key2': ['one', 'two', 'one'], 
                     'lval': [1, 2, 3]})

right = pd.DataFrame({'key1': ['foo', 'foo', 'bar', 'bar'], 
                      'key2': ['one', 'one', 'one', 'two'], 
                      'rval': [4, 5, 6, 7]})
                      

pd.merge(left, right, on=['key1', 'key2'], how='outer')
Out[591]: 
  key1 key2  lval  rval
0  foo  one   1.0   4.0
1  foo  one   1.0   5.0
2  foo  two   2.0   NaN
3  bar  one   3.0   6.0
4  bar  two   NaN   7.0

哪一种key组合会出现在结果里取决于merge方法的选择,可以把多个key当做一个tuple组成的单一key(尽管实际上并不是这样)。

注意:当我们讲列和列进行连接时,DataFrame中的index对象会被丢弃。

最后一个问题是在做merge操作的时候,如何处理重叠的列名。当我们想要手动去解决重叠问题时(参考重命名axis labels的部分),merge有一个suffixes选项,能让我们指定字符串,添加重叠的列名到左、右DataFrame:

pd.merge(left, right, on='key1')
Out[592]: 
  key1 key2_x  lval key2_y  rval
0  foo    one     1    one     4
1  foo    one     1    one     5
2  foo    two     2    one     4
3  foo    two     2    one     5
4  bar    one     3    one     6
5  bar    one     3    two     7
pd.merge(left, right, on='key1', suffixes=('_left', '_right'))
Out[593]: 
  key1 key2_left  lval key2_right  rval
0  foo       one     1        one     4
1  foo       one     1        one     5
2  foo       two     2        one     4
3  foo       two     2        one     5
4  bar       one     3        one     6
5  bar       one     3        two     7
img
img

indicator 添加特殊的列_merge,它可以指明每个行的来源,它的值有left_only、right_only或both,根据每行的合并数据的来源。

2 在index上做归并

在一些情况下,用于归并的key(键),可能是DataFrame中的index。这种情况下,可以使用left_index=True 或 right_index=True来指明,哪一个index被用来作为归并键:

left1 = pd.DataFrame({'key': ['a', 'b', 'a', 'a', 'b', 'c'], 
                      'value': range(6)})

left1

Out[595]: 
  key  value
0   a      0
1   b      1
2   a      2
3   a      3
4   b      4
5   c      5
right1 = pd.DataFrame({'group_val': [3.5, 7]}, index=['a', 'b'])
right1

Out[596]: 
   group_val
a        3.5
b        7.0
pd.merge(left1, right1, left_on='key', right_index=True)
Out[597]: 
  key  value  group_val
0   a      0        3.5
2   a      2        3.5
3   a      3        3.5
1   b      1        7.0
4   b      4        7.0

merge的默认方法是用key的交集,我们也可以设定用合集,即outer join:

pd.merge(left1, right1, left_on='key', right_index=True, how='outer')
Out[598]: 
  key  value  group_val
0   a      0        3.5
2   a      2        3.5
3   a      3        3.5
1   b      1        7.0
4   b      4        7.0
5   c      5        NaN

对于那些有多层级索引的数据,就更复杂了。index上的merge默认会是multiple-key merge(复数键归并):

lefth = pd.DataFrame({'key1': ['Ohio', 'Ohio', 'Ohio',
                               'Nevada', 'Nevada'], 
                      'key2': [2000, 2001, 2002, 2001, 2002], 
                      'data': np.arange(5.)})
lefth
                      
Out[606]: 
   data    key1  key2
0   0.0    Ohio  2000
1   1.0    Ohio  2001
2   2.0    Ohio  2002
3   3.0  Nevada  2001
4   4.0  Nevada  2002

righth = pd.DataFrame(np.arange(12).reshape((6, 2)),
                      index=[['Nevada', 'Nevada', 'Ohio', 'Ohio', 
                              'Ohio', 'Ohio'], 
                             [2001, 2000, 2000, 2000, 2001, 2002]], 
                      columns=['event1', 'event2'])
righth
                      
Out[607]: 
             event1  event2
Nevada 2001       0       1
       2000       2       3
Ohio   2000       4       5
       2000       6       7
       2001       8       9
       2002      10      11

在这个例子里,我们必须指明将多列归并作为一个list(注意处理重复index的方法是令how='outer'):

pd.merge(lefth, righth, left_on=['key1', 'key2'], 
         right_index=True)
         
Out[608]: 
   data    key1  key2  event1  event2
0   0.0    Ohio  2000       4       5
0   0.0    Ohio  2000       6       7
1   1.0    Ohio  2001       8       9
2   2.0    Ohio  2002      10      11
3   3.0  Nevada  2001       0       1

pd.merge(lefth, righth, left_on=['key1', 'key2'],
         right_index=True, how='outer')
         
Out[609]: 
   data    key1  key2  event1  event2
0   0.0    Ohio  2000     4.0     5.0
0   0.0    Ohio  2000     6.0     7.0
1   1.0    Ohio  2001     8.0     9.0
2   2.0    Ohio  2002    10.0    11.0
3   3.0  Nevada  2001     0.0     1.0
4   4.0  Nevada  2002     NaN     NaN
4   NaN  Nevada  2000     2.0     3.0

同时使用两个对象里的index来归并也是可能的:

left2 = pd.DataFrame([[1., 2.], [3., 4.], [5., 6.]], 
                     index=['a', 'c', 'e'], 
                     columns=['Ohio', 'Nevada'])

left2

Out[610]: 
   Ohio  Nevada
a   1.0     2.0
c   3.0     4.0
e   5.0     6.0
right2 = pd.DataFrame([[7., 8.], [9., 10.], [11., 12.], [13, 14]], 
                      index=['b', 'c', 'd', 'e'],
                      columns=['Missouri', 'Alabama'])
right2
                      
Out[611]: 
   Missouri  Alabama
b       7.0      8.0
c       9.0     10.0
d      11.0     12.0
e      13.0     14.0
pd.merge(left2, right2, how='outer', left_index=True, right_index=True)
Out[612]: 
   Ohio  Nevada  Missouri  Alabama
a   1.0     2.0       NaN      NaN
b   NaN     NaN       7.0      8.0
c   3.0     4.0       9.0     10.0
d   NaN     NaN      11.0     12.0
e   5.0     6.0      13.0     14.0

DataFrame有一个很便利的join实例,可以直接用index来连接。这个也可以用于与其他DataFrame进行连接,要有一样的index但不能有重叠的列:

left2.join(right2, how='outer')
Out[615]: 
   Ohio  Nevada  Missouri  Alabama
a   1.0     2.0       NaN      NaN
b   NaN     NaN       7.0      8.0
c   3.0     4.0       9.0     10.0
d   NaN     NaN      11.0     12.0
e   5.0     6.0      13.0     14.0

最后,对于简单的index-on-index连接,可以直接给join传入一个DataFrame。(作为备选,也可以使用最普遍的concat函数,这个在下一节会做介绍):

another = pd.DataFrame([[7., 8.], [9., 10.], [11., 12.], [16., 17.]], 
                       index=['a', 'c', 'e', 'f'], 
                       columns=['New York', 'Oregon'])
another
                       
Out[616]: 
   New York  Oregon
a       7.0     8.0
c       9.0    10.0
e      11.0    12.0
f      16.0    17.0

left2.join([right2, another])
Out[617]: 
   Ohio  Nevada  Missouri  Alabama  New York  Oregon
a   1.0     2.0       NaN      NaN       7.0     8.0
c   3.0     4.0       9.0     10.0       9.0    10.0
e   5.0     6.0      13.0     14.0      11.0    12.0
left2.join([right2, another], how='outer')
Out[618]: 
   Ohio  Nevada  Missouri  Alabama  New York  Oregon
a   1.0     2.0       NaN      NaN       7.0     8.0
b   NaN     NaN       7.0      8.0       NaN     NaN
c   3.0     4.0       9.0     10.0       9.0    10.0
d   NaN     NaN      11.0     12.0       NaN     NaN
e   5.0     6.0      13.0     14.0      11.0    12.0
f   NaN     NaN       NaN      NaN      16.0    17.0

2 沿着轴串联

另一种结合方式被称为可互换的,比如concatenation, binding, or stacking(串联,绑定,堆叠)。Numpy中的concatenate函数可以作用于numpy 数组:

arr = np.arange(12.).reshape((3, 4))
arr

Out[621]: 
array([[ 0.,  1.,  2.,  3.],
       [ 4.,  5.,  6.,  7.],
       [ 8.,  9., 10., 11.]])

np.concatenate([arr, arr], axis=1)
Out[622]: 
array([[ 0.,  1.,  2.,  3.,  0.,  1.,  2.,  3.],
       [ 4.,  5.,  6.,  7.,  4.,  5.,  6.,  7.],
       [ 8.,  9., 10., 11.,  8.,  9., 10., 11.]])       

而在pandas的对象中,比如Series和DataFrame,labeled axes(便签化的轴)能让我们做更泛化的数组串联操作。不过我们可能会有下面一些疑问:

  • 如果一个对象在其他轴上的index不同,我们应不应该在这些轴上把不同的元素合并起来,或者只用交集?
  • 经过串联操作后,连接的部分在输出对象里应不应该是可被识别的?
  • concatenation axis(串联轴)含有的数据需要被保留吗?在很多情况下,DataFrame中一些用整数做的label(标签)其实最好在串联后被删除。

pandas中的concat函数能解决上面这些问题。这里会给出几个例子来说明。假设我们有三个Series,他们指明没有index overlap(索引重叠):

s1 = pd.Series([0, 1], index=['a', 'b'])

s2 = pd.Series([2, 3, 4], index=['c', 'd', 'e'])

s3 = pd.Series([5, 6], index=['f', 'g'])

调用concat,把上面的series放在一个list里,结果会把值和索引都整合在一起:

pd.concat([s1, s2, s3])
Out[624]: 
a    0
b    1
c    2
d    3
e    4
f    5
g    6
dtype: int64

默认情况下,concat中axis=0,结果会得到一个新的而series。如果令axis=1, 结果会变成一个DataFrame(axis=1 是列):

In [42]:

pd.concat([s1, s2, s3], axis=1)
Out[625]: 
     0    1    2
a  0.0  NaN  NaN
b  1.0  NaN  NaN
c  NaN  2.0  NaN
d  NaN  3.0  NaN
e  NaN  4.0  NaN
f  NaN  NaN  5.0
g  NaN  NaN  6.0

这种情况下,不会与其他轴产生重叠,效果与join中的outer join一样。你也可以通过设定join='inner'来使用交集:

s4 = pd.concat([s1, s3])
s4

Out[628]: 
a    0
b    1
f    5
g    6
dtype: int64
pd.concat([s1, s4], axis=1)
Out[629]: 
     0  1
a  0.0  0
b  1.0  1
f  NaN  5
g  NaN  6
pd.concat([s1, s4], axis=1, join='inner')
Out[630]: 
   0  1
a  0  0
b  1  1

因为join='inner',所以f和g标签消失了。

你也可以在join_axes中指定使用哪些轴:

pd.concat([s1, s4], axis=1, join_axes=[['a', 'c', 'b', 'e']])
Out[631]: 
     0    1
a  0.0  0.0
c  NaN  NaN
b  1.0  1.0
e  NaN  NaN

一个潜在的问题是串联的部分在结果里是不可辨识的。假设我们想在串联轴上创建一个多层级索引,我们需要用到keys参数:

result = pd.concat([s1, s1, s3], keys=['one', 'two', 'three'])
result

Out[633]: 
one    a    0
       b    1
two    a    0
       b    1
three  f    5
       g    6
dtype: int64

result.unstack()
Out[634]: 
         a    b    f    g
one    0.0  1.0  NaN  NaN
two    0.0  1.0  NaN  NaN
three  NaN  NaN  5.0  6.0

如果是设定axis=1,那么keys会变为DataFrame的column header(列头):


print(s1)
print(s2)
print(s3)

a    0
b    1
dtype: int64
c    2
d    3
e    4
dtype: int64
f    5
g    6
dtype: int64
pd.concat([s1, s2, s3], axis=1, keys=['one', 'two', 'three'])
Out[636]: 
   one  two  three
a  0.0  NaN    NaN
b  1.0  NaN    NaN
c  NaN  2.0    NaN
d  NaN  3.0    NaN
e  NaN  4.0    NaN
f  NaN  NaN    5.0
g  NaN  NaN    6.0

这种逻辑也可以扩展到DataFrame对象上:

df1 = pd.DataFrame(np.arange(6).reshape(3, 2), index=['a', 'b', 'c'], 
                   columns=['one', 'two'])

df1

Out[637]: 
   one  two
a    0    1
b    2    3
c    4    5
df2 = pd.DataFrame(5 + np.arange(4).reshape(2, 2), index=['a', 'c'], 
                   columns=['three', 'four'])
df2
                   
Out[638]: 
   three  four
a      5     6
c      7     8
pd.concat([df1, df2], axis=1, keys=['level1', 'level2'])
Out[639]: 
  level1     level2     
     one two  three four
a      0   1    5.0  6.0
b      2   3    NaN  NaN
c      4   5    7.0  8.0

如果导入一个dict而不是list,那么dict的key会被用于上面concat中的keys选项:

pd.concat({'level1': df1, 'level2': df2}, axis=1)
Out[640]: 
  level1     level2     
     one two  three four
a      0   1    5.0  6.0
b      2   3    NaN  NaN
c      4   5    7.0  8.0

还有其他一些选项负责多层级索引的设定(表8-3)。比如,可以给创建的axis level(轴层级)用names参数来命名:

pd.concat([df1, df2], axis=1, keys=['level1', 'level2'],
          names=['upper', 'lower'])
          
Out[641]: 
upper level1     level2     
lower    one two  three four
a          0   1    5.0  6.0
b          2   3    NaN  NaN
c          4   5    7.0  8.0

最后我们关心的是,在DataFrame中,行索引(row index)没有包含相关的数据:

df1 = pd.DataFrame(np.random.randn(3, 4), columns=['a', 'b', 'c', 'd'])
df1

Out[642]: 
          a         b         c         d
0  0.681009  0.974517 -0.736966 -0.902725
1 -0.049008  0.339831 -0.266341 -0.663389
2  0.128945 -0.181098 -0.170917  0.024014
df2 = pd.DataFrame(np.random.randn(2, 3), columns=['b', 'd', 'a'])
df2

Out[643]: 
          b         d         a
0  0.797382  0.533538  0.440353
1  0.268646 -0.330523 -1.575735

这种情况下,可以设置ignore_index=True:

pd.concat([df1, df2], ignore_index=True)
Out[644]: 
          a         b         c         d
0  0.681009  0.974517 -0.736966 -0.902725
1 -0.049008  0.339831 -0.266341 -0.663389
2  0.128945 -0.181098 -0.170917  0.024014
3  0.440353  0.797382       NaN  0.533538
4 -1.575735  0.268646       NaN -0.330523
img

3 用重叠来合并数据

另一种数据合并方法既不属于merge,也不属于concatenation。比如两个数据集,index可能完全覆盖,或覆盖一部分。这里举个例子,考虑下numpy的where函数,可以在数组上进行类似于if-else表达式般的判断:


a = pd.Series([np.nan, 2.5, np.nan, 3.5, 4.5, np.nan], 
              index=['f', 'e', 'd', 'c', 'b', 'a'])

a

Out[645]: 
f    NaN
e    2.5
d    NaN
c    3.5
b    4.5
a    NaN
dtype: float64

b = pd.Series(np.arange(len(a), dtype=np.float64), 
              index=['f', 'e', 'd', 'c', 'b', 'a'])
b
              
Out[646]: 
f    0.0
e    1.0
d    2.0
c    3.0
b    4.0
a    5.0
dtype: float64

np.where(pd.isnull(a), b, a)
Out[647]: array([0. , 2.5, 2. , 3.5, 4.5, 5. ])

Series有一个combine_first方法,效果和上面是一样,而且还会自动对齐(比如把index按字母进行排列):


b[:-2].combine_first(a[2:])
Out[648]: 
a    NaN
b    4.5
c    3.0
d    2.0
e    1.0
f    0.0
dtype: float64

对于DataFrame, combine_first可以在列与列之间做到同样的事情,可以认为是用传递的对象,给调用对象中的缺失值打补丁:

df1 = pd.DataFrame({'a': [1., np.nan, 5., np.nan], 
                    'b': [np.nan, 2., np.nan, 6.], 
                    'c': range(2, 18, 4)})

df1

Out[649]: 
     a    b   c
0  1.0  NaN   2
1  NaN  2.0   6
2  5.0  NaN  10
3  NaN  6.0  14

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

推荐阅读更多精彩内容