使用pandas聚合所有数据帧行对组合

ale*_*hli 6 python combinations aggregate python-itertools pandas

我使用python pandas跨数据帧执行分组和聚合,但我现在想执行特定的行成对聚合(n选择2,统计组合).这是示例数据,我想在[mygenes]中查看所有基因对:

import pandas
import itertools

mygenes=['ABC1', 'ABC2', 'ABC3', 'ABC4']

df = pandas.DataFrame({'Gene' : ['ABC1', 'ABC2', 'ABC3', 'ABC4','ABC5'],
                       'case1'   : [0,1,1,0,0],
                       'case2'   : [1,1,1,0,1],
                       'control1':[0,0,1,1,1],
                       'control2':[1,0,0,1,0] })
>>> df
   Gene  case1  case2  control1  control2
0  ABC1      0      1         0         1
1  ABC2      1      1         0         0
2  ABC3      1      1         1         0
3  ABC4      0      0         1         1
4  ABC5      0      1         1         0
Run Code Online (Sandbox Code Playgroud)

最终产品应如下所示(默认情况下应用np.sum很好):

                 case1    case2    control1    control2
'ABC1', 'ABC2'    1         2         0            1
'ABC1', 'ABC3'    1         2         1            1
'ABC1', 'ABC4'    0         1         1            2
'ABC2', 'ABC3'    2         2         1            0
'ABC2', 'ABC4'    1         1         1            1
'ABC3', 'ABC4'    1         1         2            1 
Run Code Online (Sandbox Code Playgroud)

使用itertools($ itertools.combinations(mygenes, 2))可以很容易地获得一组基因对,但我无法弄清楚如何根据它们的值执行特定行的聚合.任何人都可以建议吗?谢谢

DSM*_*DSM 8

我无法想到一个聪明的矢量化方法来做到这一点,但除非性能是一个真正的瓶颈,我倾向于使用最简单的事情,这是有道理的.在这种情况下,我可能会set_index("Gene")然后loc用来挑选行:

>>> df = df.set_index("Gene")
>>> cc = list(combinations(mygenes,2))
>>> out = pd.DataFrame([df.loc[c,:].sum() for c in cc], index=cc)
>>> out
              case1  case2  control1  control2
(ABC1, ABC2)      1      2         0         1
(ABC1, ABC3)      1      2         1         1
(ABC1, ABC4)      0      1         1         2
(ABC2, ABC3)      2      2         1         0
(ABC2, ABC4)      1      1         1         1
(ABC3, ABC4)      1      1         2         1
Run Code Online (Sandbox Code Playgroud)

  • ..嘿,等等。140 万行 * 6000 列是 84 亿个数字。即使每个值只使用 1 个字节,也就是 8G。这将有点难以管理(当我意识到使用浮点数时没有内存时,我正在对它进行矢量化。) (3认同)

Joh*_*hnE 3

在走得太远之前,您应该记住您的数据会变得非常快。如果有 5 行,输出将为C(5,2)or5+4+3+2+1等​​等。

也就是说,我会考虑在 numpy 中执行此操作以提高速度(顺便说一句,您可能想在问题中添加 numpy 标签)。不管怎样,这并不像它可能的那样矢量化,但至少应该是一个开始:

df2 = df.set_index('Gene').loc[mygenes].reset_index()

import math
sz = len(df2)
sz2 = math.factorial(sz) / ( math.factorial(sz-2) * 2 )

Gene = df2['Gene'].tolist()
abc = df2.ix[:,1:].values

import math
arr = np.zeros([sz2,4])
gene2 = []
k = 0

for i in range(sz):
    for j in range(sz):
        if i != j and i < j:
            gene2.append( gene[i] + gene[j] )
            arr[k] = abc[i] + abc[j]
            k += 1

pd.concat( [ pd.DataFrame(gene2), pd.DataFrame(arr) ], axis=1 )
Out[1780]: 
          0  0  1  2  3
0  ABC1ABC2  1  2  0  1
1  ABC1ABC3  1  2  1  1
2  ABC1ABC4  0  1  1  2
3  ABC2ABC3  2  2  1  0
4  ABC2ABC4  1  1  1  1
5  ABC3ABC4  1  1  2  1
Run Code Online (Sandbox Code Playgroud)

根据大小/速度问题,您可能需要将字符串和数字代码分开并对数字部分进行矢量化。如果您的数据很大,那么该代码不太可能很好地扩展,如果是的话,这可能会决定您需要什么样的答案(并且还可能需要考虑如何存储结果)。