2

我有一个带有生物名称及其抗生素敏感性列表的熊猫数据框。我希望根据以下规则将所有生物体合并到下面的 DataFrame 中的一列中。

  1. 如果 ORG1 == A,什么也不做;

  2. 如果 ORG1 != A 和 ORG2 == A,将 ORG2 值移动到 ORG1 列

  3. 如果 ORG1 != A 和 ORG3 == A,将 ORG3 值移动到 ORG1 列

如果满足条件 2,以及将 ORG2 值移动到 ORG1 列,还将 AS20* 中的列值移动到 AS10*。

同样,如果满足条件 3,并且将 ORG3 值移动到 ORG1 列,还将 AS30* 中的列值移动到 AS10*。

我通过根据上述规则编写一个函数自己尝试了这一点,并且基于以下几点取得了有限的成功:

If ORG2 == A:
       return ORG1.map(ORG2)

当我尝试根据条件依次映射 AS201 -> AS101、AS202 -> AS102、AS203 -> AS103 等时,我迷路了。

我遇到的另一个问题是有机体名称不是单个字母,漂亮的也不是。示例中的 A 相当于re.match('aureus')我的数据集中的 A。

此外,每个 ORG 列有 20 个 AS 列,超过 150,000 条记录,因此我希望使其适用于任何数量的抗生素敏感性结果。

我有点挣扎,所以在正确的方向上推几下真的会有所帮助。

提前致谢。

索引 ORG1 ORG2 ORG3 AB1 AS101 AS201 AS301 AB2 AS102 AS202 AS302
1 A NaN NaN 笔 S NaN NaN dfluc S NaN NaN
2 ABC pen RSS dfluc SRS
3 BAB pen SSR dfluc SSR
4 A NaN NaN pen R NaN NaN dfluc S NaN NaN
5 A NaN NaN pen R NaN NaN dfluc S NaN NaN
6 CAA 笔 SRR dfluc RSR
7 B NaN A pen R NaN S dfluc S NaN S
8 ABA 笔 RRR dfluc RRR
9 A NaN NaN pen R NaN NaN dfluc S NaN NaN
4

1 回答 1

2

我们可以选择行 whereORG1 != AORG2 == Awith

mask = (df['ORG1'] != 'A')&(df[orgi] == 'A')

mask然后是一个布尔系列。要将值从 ORG2 复制到 ORG1,我们可以使用

df['ORG1'][mask] = df['ORG2'][mask]

或者,因为我们知道右边的值是A,我们可以使用

df['ORG1'][mask] = 'A'

可以类似地复制 AS 列。


我们可以找到其列值包含一些字符串的行,例如'aureus'with

df[orgi].str.contains('aureus') == True

str.contains可以将任何正则表达式模式作为其参数。请参阅文档:矢量化字符串方法

注意:通常使用df[orgi].str.contains('aureus')(没有== True, 但由于df[orgi]可能包含NaN值,我们还需要将NaNs 映射到 False,因此我们使用df[orgi].str.contains('aureus') == True.


import pandas as pd

filename = 'data.txt'
df = pd.read_table(filename, delimiter='\s+')
print(df)
#    Index ORG1 ORG2 ORG3  AB1 AS101 AS201 AS301    AB2 AS102 AS202 AS302
# 0      1    A  NaN  NaN  pen     S   NaN   NaN  dfluc     S   NaN   NaN
# 1      2    A    B    C  pen     R     S     S  dfluc     S     R     S
# 2      3    B    A    B  pen     S     S     R  dfluc     S     S     R
# 3      4    A  NaN  NaN  pen     R   NaN   NaN  dfluc     S   NaN   NaN
# 4      5    A  NaN  NaN  pen     R   NaN   NaN  dfluc     S   NaN   NaN
# 5      6    C    A    A  pen     S     R     R  dfluc     R     S     R
# 6      7    B  NaN    A  pen     R   NaN     S  dfluc     S   NaN     S
# 7      8    A    B    A  pen     R     R     R  dfluc     R     R     R
# 8      9    A  NaN  NaN  pen     R   NaN   NaN  dfluc     S   NaN   NaN

for i in range(2,4):
    orgi = 'ORG{i}'.format(i=i)
    # mask = (df['ORG1'] != 'A')&(df[orgi] == 'A')
    mask = (df['ORG1'].str.contains('A') == False)&(df[orgi].str.contains('A') == True)
    # Move ORGi --> ORG1
    df['ORG1'][mask] = df[orgi][mask]
    for j in range(1,4):
        # Move ASij --> AS1j
        source_as = 'AS{i}{j:02d}'.format(i=i, j=j)
        target_as = 'AS1{j:02d}'.format(i=i, j=j)
        try:
            df[target_as][mask] = df[source_as][mask]
        except KeyError:
            pass

print(df)

产量

   Index ORG1 ORG2 ORG3  AB1 AS101 AS201 AS301    AB2 AS102 AS202 AS302
0      1    A  NaN  NaN  pen     S   NaN   NaN  dfluc     S   NaN   NaN
1      2    A    B    C  pen     R     S     S  dfluc     S     R     S
2      3    A    A    B  pen     S     S     R  dfluc     S     S     R
3      4    A  NaN  NaN  pen     R   NaN   NaN  dfluc     S   NaN   NaN
4      5    A  NaN  NaN  pen     R   NaN   NaN  dfluc     S   NaN   NaN
5      6    A    A    A  pen     R     R     R  dfluc     S     S     R
6      7    A  NaN    A  pen     S   NaN     S  dfluc     S   NaN     S
7      8    A    B    A  pen     R     R     R  dfluc     R     R     R
8      9    A  NaN  NaN  pen     R   NaN   NaN  dfluc     S   NaN   NaN

请注意, ifORG2 == AORG3 == A, then 中的值AS20*AS30*都竞争覆盖 column 中的值AS10*。我不确定你想赢得哪个价值。在上面的代码中,最后一列获胜,即AS30*.

于 2013-04-14T09:40:20.293 回答