Python 检查是否存在具有特定值的行,如果不存在则创建

Python 检查是否存在具有特定值的行,如果不存在则创建,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个包含数千个原点(a列)和数千个目标点(B列)的大表,还有一个带值的列。我需要一个python中的高效算法来确保从原点到目标的每一对都有一行,如果没有,就创建它 例如,假设我有三个原点(1,2,3)和三个终点(1,2,3)。目前,我的数据没有一行用于起点(a列)和目的地(B列)之间的每个可能的对,如下所示: Index A B Value 0 1 1 V11 1 1 3 V13 2 2 1

我有一个包含数千个原点(a列)和数千个目标点(B列)的大表,还有一个带值的列。我需要一个python中的高效算法来确保从原点到目标的每一对都有一行,如果没有,就创建它

例如,假设我有三个原点(1,2,3)和三个终点(1,2,3)。目前,我的数据没有一行用于起点(a列)和目的地(B列)之间的每个可能的对,如下所示:

Index  A      B     Value
0      1      1     V11
1      1      3     V13
2      2      1     V21
3      2      2     V22
4      2      3     V23
5      3      1     V31
6      3      3     V33
我想要一个python脚本,使其看起来像:

Index  A      B     Value
0      1      1     V11
1      1      2     NA
2      1      3     V13
3      2      1     V21
4      2      2     V22
5      2      3     V23
6      3      1     V31
7      3      2     NA
8      3      3     V33

这是使用
itertools.product
的一种方法

其思想是计算完整的组合集,删除已经存在的组合,然后将剩余的添加到数据帧中

from itertools import product

maxval = df[['A', 'B']].max().max()

prod = set(product(range(1, maxval+1), range(1, maxval+1)))
existing = set(map(tuple, df[['A', 'B']].values))

additional = pd.DataFrame(np.array(list(prod - existing)), columns=['A', 'B'])

res = pd.concat([df.set_index('Index'), additional], axis=0)\
        .sort_values(['A', 'B'])\
        .reset_index(drop=True)\
        .reset_index()

print(res)

   index  A  B Value
0      0  1  1   V11
1      1  1  2   NaN
2      2  1  3   V13
3      3  2  1   V21
4      4  2  2   V22
5      5  2  3   V23
6      6  3  1   V31
7      7  3  2   NaN
8      8  3  3   V33
您可以使用:

df.set_index(['A','B'])\
  .unstack()\
  .stack(dropna=False)\
  .reset_index()
输出:

   A  B Value
0  1  1   V11
1  1  2  None
2  1  3   V13
3  2  1   V21
4  2  2   V22
5  2  3   V23
6  3  1   V31
7  3  2  None
8  3  3   V33
工作原理:


首先,创建一个多索引。使用默认级别为-1的最内部索引取消堆栈,这将创建一个矩阵,其中a作为行,B作为列,并使用匹配值填充该矩阵。在没有匹配值的地方,将分配None/NaN。现在,我们可以使用带有参数dropna=False的stack来保留所有值,包括None/NaN值。

尝试
pivot
melt

df.pivot(index='A',columns='B',values='Value').reset_index().melt('A').sort_values('A')
Out[338]: 
   A  B value
0  1  1   V11
3  1  2  None
6  1  3   V13
1  2  1   V21
4  2  2   V22
7  2  3   V23
2  3  1   V31
5  3  2  None
8  3  3   V33

这是我将使用的方式:-)@Wen。。。谢谢。这真是太棒了,效果和我预期的一样!我很感激jpp。