我有一个包含数千个原点(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
答案 0 :(得分:4)
这是使用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
答案 1 :(得分:4)
您可以使用:
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
工作原理:
首先,创建一个MultiIndex。使用默认级别-1为最内层索引的unstack,这将创建一个矩阵,其中A为行,B为列,使用匹配的值填充该矩阵。在没有匹配值的地方,分配无/ NaN。现在,我们可以使用带有参数dropna = False的堆栈来保留所有值,包括None / NaN值。
答案 2 :(得分:2)
尝试SELECT *
FROM dblink('dbname=mydb options=-csearch_path=',
'select proname, prosrc from pg_proc')
AS t1(proname name, prosrc text)
WHERE proname LIKE 'bytea%';
和pivot
melt
答案 3 :(得分:0)
具有stack / unstack或pivot的解决方案的先决条件是“A”和“B”列中必须存在所有可能的点。这两列中缺少的任何一点,结果都是错误的。例如,删除原始数据中的 Index = 3(V22),结果变为:
In []: df.set_index(['A','B']).unstack().stack(dropna=False).reset_index()
Out[]:
A B Value
0 1 1 V11
1 1 3 V13
2 2 1 V21
3 2 3 V23
4 3 1 V31
5 3 3 V33
更强大的解决方案是使用reindex()来强制生成具有预定义点和顺序的行,因此不必担心任何潜在的缺失点。即:
In []: midx = pd.MultiIndex.from_product([[1,2,3],[1,2,3]],names=list('AB'))
In []: df.set_index(['A','B']).reindex(midx).reset_index()
Out[]:
A B Value
0 1 1 V11
1 1 2 NaN
2 1 3 V13
3 2 1 V21
4 2 2 NaN
5 2 3 V23
6 3 1 V31
7 3 2 NaN
8 3 3 V33