如何组织 DataFrame 列

hir*_*iro 6 python chemistry pandas

我试图根据特定规则组织 DataFrame 列,但我不知道方法。

\n

例如,我有一个与化学相关的 DataFrame,如下所示。\n每行显示化合物中化学键的数量。

\n
   OH  HO  CaO  OCa  OO  NaMg  MgNa\n0   2   3    2    0   1     1     1\n1   0   2    3    4   5     2     0\n2   1   2    3    0   0     0     0\n
Run Code Online (Sandbox Code Playgroud)\n

在化学中,OH(氧-氢)键等于HO(氢-氧)键,CaO(钙-氧)键等于OCa(氧-钙)键。因此,我想组织 DataFrame 如下所示。

\n
   OH  CaO  OO  NaMg \n0   5    2   1     2\n1   2    7   9     2\n2   3    3   0     0\n
Run Code Online (Sandbox Code Playgroud)\n

我\xe2\x80\x99m 挣扎是因为:

\n
    \n
  • 我的真实DataFrame中有多种化学键,所以不可能一一整理信息(列数超过3000,我不知道哪些化学键存在并且是重复的。)
  • \n
  • 字母数量取决于每个元素符号,有些符号包含小写\n(例如氢:H(一个字母且仅大写),钙:Ca(两个字母且大小写)
  • \n
\n

我在网上找了同样的问题,自己写了代码,但没找到方法。我想知道解决我的问题的代码。

\n

Cor*_*ien 6

您可以使用str.findall提取单个元素并使用frozenset和排序单个元素来重新组织对。使用frozenset并不是一个好的解决方案,因为对于OO,第二个将会丢失。

现在您可以按此集合进行分组并应用总和:

# Modified from https://www.johndcook.com/blog/2016/02/04/regular-expression-to-match-a-chemical-element/
pat = r'(A[cglmrstu]|B[aehikr]?|C[adeflmnorsu]?|D[bsy]|E[rsu]|F[elmr]?|G[ade]|H[efgos]?|I[nr]?|Kr?|L[airuv]|M[dgnot]|N[abdeiop]?|Os?|P[abdmortu]?|R[abefghnu]|S[bcegimnr]?|T[abcehilm]|U(?:u[opst])?|V|W|Xe|Yb?|Z[nr])'

grp = df.columns.str.findall(pat).map(lambda x: tuple(sorted(x))))
out = df.groupby(grp, axis=1).sum().rename(columns=''.join)
Run Code Online (Sandbox Code Playgroud)

输出:

>>> out
   CaO  HO  MgNa  OO
0    2   5     2   1
1    7   2     2   5
2    3   3     0   0
Run Code Online (Sandbox Code Playgroud)