0

我有关于 pulications 的数据,其中包含 issn、year、volume 和 issue。所以例如

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
....

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

我的熊猫知识还是很基础的。我有一种感觉,我应该能够用几行聪明的熊猫代码来识别缺失的值,但我不明白。任何提示如何解决?

4

2 回答 2

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.]
于 2013-04-09T14:39:47.817 回答
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]
于 2013-04-09T15:02:36.863 回答