使用pandas查找数据中的“空白”

时间:2013-04-09 13:50:51

标签: python pandas time-series

我有关于脉动的数据,其中包含发布,年份,数量和问题。例如,

1234-x000, 2013, 1, 2
1234-x000, 2013, 1, 1
1234-x000, 2012, 6, 2
1234-x000, 2012, 6, 1
1234-x000, 2012, 5, 2
....
4321-yyyy, 2013, 2, 1
4321-yyyy, 2013, 1, 1
4321-yyyy, 2012, 12, 1
4321-yyyy, 2012, 11, 1
....

我想识别缺失的数据。一个问题是,体积/问题结构并不总是相同的。因此,对于一个问题,每卷可能有12个问题,或者只有6个问题或......但是每年发布的数量可以假定是固定的。

我的熊猫知识仍然非常基础。我有这种感觉,我应该能够通过几行聪明的熊猫代码来识别缺失的值,但我不明白。任何提示如何解决?

2 个答案:

答案 0 :(得分:0)

这不是一个完整的解决方案,例如它假设,最后一个卷始终存在。但是当你要求一个指针时,这应该让你走了:

In [28]: df
Out[28]: 
        issn  year  vol  issue
0  1234-x000  2013    1      2
1  1234-x000  2013    1      1
2  1234-x000  2012    6      2
3  1234-x000  2012    6      1
4  1234-x000  2012    5      2
5  4321-yyyy  2013    2      1
6  4321-yyyy  2013    1      1
7  4321-yyyy  2012   12      1
8  4321-yyyy  2012   11      1

In [29]: vols = df.groupby('issn').vol.max()

In [30]: vols
Out[30]: 
issn
1234-x000     6
4321-yyyy    12
Name: vol

In [31]: for k, g in df.groupby(['issn','year']):
    ...:     print k
    ...:     print 'missing: ', np.setdiff1d(np.arange(1, vols[k[0]]+1),
    ...:                                                g.issue.values)

输出:

('1234-x000', 2012)
missing:  [ 3.  4.  5.  6.]
('1234-x000', 2013)
missing:  [ 3.  4.  5.  6.]
('4321-yyyy', 2012)
missing:  [  2.   3.   4.   5.   6.   7.   8.   9.  10.  11.  12.]
('4321-yyyy', 2013)
missing:  [  2.   3.   4.   5.   6.   7.   8.   9.  10.  11.  12.]

答案 1 :(得分:0)

这是一种方式。我会添加两列“idx”和“max”

In [452]: df['idx'] = df.groupby(['issn']).apply(lambda sdf: (sdf.volume - 1) * sdf.issue.max() + sdf.issue)

In [453]: df
Out[453]:
        issn  year  volume  issue  idx
0  1234-x000  2013       1      2    2
1  1234-x000  2013       1      1    1
2  1234-x000  2012       6      2   12
3  1234-x000  2012       6      1   11
4  1234-x000  2012       5      2   10
5  4321-yyyy  2013       2      1    2
6  4321-yyyy  2013       1      1    1
7  4321-yyyy  2012      12      1   12
8  4321-yyyy  2012      11      1   11

In [454]: df['max'] = df.groupby(['issn']).idx.transform(lambda s: s.max())

In [455]: df
Out[455]:
        issn  year  volume  issue  idx  max
0  1234-x000  2013       1      2    2   12
1  1234-x000  2013       1      1    1   12
2  1234-x000  2012       6      2   12   12
3  1234-x000  2012       6      1   11   12
4  1234-x000  2012       5      2   10   12
5  4321-yyyy  2013       2      1    2   12
6  4321-yyyy  2013       1      1    1   12
7  4321-yyyy  2012      12      1   12   12
8  4321-yyyy  2012      11      1   11   12

上一个答案提供了其余的

In [462]: df.groupby(['issn', 'year']).apply(lambda sdf: np.setdiff1d(range(1, sdf['max'].irow(0)), sdf.idx).tolist())
Out[462]:
issn       year
1234-x000  2012        [1, 2, 3, 4, 5, 6, 7, 8, 9]
           2013      [3, 4, 5, 6, 7, 8, 9, 10, 11]
4321-yyyy  2012    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
           2013      [3, 4, 5, 6, 7, 8, 9, 10, 11]