使用pandas计算匹配字符串和数字的行

时间:2015-08-11 21:21:32

标签: python pandas

我在SAMPLE列中有1-12个数字,每个数字我都会尝试计算突变数(A:T,C:G等......)。这段代码可以工作,但是如何修改这段代码,为每个突变提供所有12个条件,而不是为每个突变编写相同的代码12次?

在这个例子中; AT给出了SAMPLE=1时的数字。我试图获得每个样本号的AT数(1,2,... 12)。那么如何修改这段代码呢?我会感激任何帮助。谢谢。

         SAMPLE                                        MUT
0          11                                 chr1:100154376:G:A
1           2                                 chr1:100177723:C:T
2           9                                 chr1:100177723:C:T
3           1                                chr1:100194200:-:AA
4           8                                  chr1:10032249:A:G
5           2                                 chr1:100340787:G:A
6           1                                 chr1:100349757:A:G
7           3                                  chr1:10041186:C:A
8          10                                 chr1:100476986:G:C
9           4                                 chr1:100572459:C:T
10          5                                 chr1:100572459:C:T
...        ...                                    ...

d= df["SAMPLE", "MUT" ]
chars1 = "TGC-"
number = {}
for item in chars1:
    dm= d[(d["MUT"].str.contains("A:" + item)) & (d["SAMPLE"].isin([1]))]
    num1 = dm.count()
    number[item] = num1

AT=number["T"]
AG=number["G"]
AC=number["C"]
A_=number["-"]

3 个答案:

答案 0 :(得分:2)

我会在pandas中使用本地字符串提取方法

df.MUT.str.extract('A:(T)|A:(G)|A:(C)|A:(-)')

返回不同组的匹配项:

      0    1    2    3
0   NaN  NaN  NaN  NaN
1   NaN  NaN  NaN  NaN
2   NaN  NaN  NaN  NaN
3   NaN  NaN  NaN  NaN
4   NaN    G  NaN  NaN
5   NaN  NaN  NaN  NaN
6   NaN    G  NaN  NaN
7   NaN  NaN  NaN  NaN
8   NaN  NaN  NaN  NaN
9   NaN  NaN  NaN  NaN
10  NaN  NaN  NaN  NaN

然后我会使用True将其转换为Falsepd.isnull,并将其反转为~。从而在匹配时获得True,而在没有匹配时获得false。

~pd.isnull(df.MUT.str.extract('A:(T)|A:(G)|A:(C)|A:(-)'))
        0      1      2      3
0   False  False  False  False
1   False  False  False  False
2   False  False  False  False
3   False  False  False  False
4   False   True  False  False
5   False  False  False  False
6   False   True  False  False
7   False  False  False  False
8   False  False  False  False
9   False  False  False  False
10  False  False  False  False

然后将其分配给数据帧

df[["T","G","C","-"]] = ~pd.isnull(df.MUT.str.extract('A:(T)|A:(G)|A:(C)|A:(-)'))

    SAMPLE                  MUT      T      G      C      -
0       11   chr1:100154376:G:A  False  False  False  False
1        2   chr1:100177723:C:T  False  False  False  False
2        9   chr1:100177723:C:T  False  False  False  False
3        1  chr1:100194200:-:AA  False  False  False  False
4        8    chr1:10032249:A:G  False   True  False  False
5        2   chr1:100340787:G:A  False  False  False  False
6        1   chr1:100349757:A:G  False   True  False  False
7        3    chr1:10041186:C:A  False  False  False  False
8       10   chr1:100476986:G:C  False  False  False  False
9        4   chr1:100572459:C:T  False  False  False  False
10       5   chr1:100572459:C:T  False  False  False  False

现在我们可以简单地对列进行求和:

df[["T","G","C","-"]].sum()
T    0
G    2
C    0
-    0

但是等等,我们还没有在SAMPLE == 1

的地方做到这一点

我们可以使用面具轻松完成此任务:

sample_one_mask = df.SAMPLE == 1
df[sample_one_mask][["T","G","C","-"]].sum()
T    0
G    1
C    0
-    0

如果您希望每个SAMPLE计算一次,您可以使用groupby函数:

df[["SAMPLE","T","G","C","-"]].groupby("SAMPLE").agg(sum).astype(int)

        T  G  C  -
SAMPLE            
1       0  1  0  0
2       0  0  0  0
3       0  0  0  0
4       0  0  0  0
5       0  0  0  0
8       0  1  0  0
9       0  0  0  0
10      0  0  0  0
11      0  0  0  0

TLDR;

这样做:

df[["T","G","C","-"]] = ~pd.isnull(df.MUT.str.extract('A:(T)|A:(G)|A:(C)|A:(-)'))
df[["SAMPLE","T","G","C","-"]].groupby("SAMPLE").agg(sum).astype(int)

答案 1 :(得分:1)

您可以使用正则表达式替换创建具有突变类型(A-> T,G-> C)的列,然后将pandas groupby应用于count。

import pandas as pd
import re
df = pd.read_table('df.tsv')
df['mutation_type'] = df['MUT'].apply(lambda x: re.sub(r'^.*?:([^:]+:[^:]+)$', r'\1', x))
df.groupby(['SAMPLE','mutation_type']).agg('count')['MUT']

您的数据输出如下:

SAMPLE  mutation_type
1       -:AA             1
        A:G              1
2       C:T              1
        G:A              1
3       C:A              1
4       C:T              1
5       C:T              1
8       A:G              1
9       C:T              1
10      G:C              1
11      G:A              1
Name: MUT, dtype: int64

答案 2 :(得分:1)

我对A.P有类似的答案。

import pandas as pd
df = pd.DataFrame(data={'SAMPLE': [11,2,9,1,8,2,1,3,10,4,5], 'MUT': ['chr1:100154376:G:A', 'chr1:100177723:C:T', 'chr1:100177723:C:T', 'chr1:100194200:-:AA', 'chr1:10032249:A:G', 'chr1:100340787:G:A', 'chr1:100349757:A:G', 'chr1:10041186:C:A', 'chr1:100476986:G:C', 'chr1:100572459:C:T', 'chr1:100572459:C:T']}, columns=['SAMPLE', 'MUT'])
df['Sequence'] = df['MUT'].str.replace(r'\w+:\d+:', '\1')
df.groupby(['SAMPLE', 'Sequence']).count()

可生产

                 MUT
SAMPLE Sequence     
1      -:AA       1
       A:G        1
2      C:T        1
       G:A        1
3      C:A        1
4      C:T        1
5      C:T        1
8      A:G        1
9      C:T        1
10     G:C        1
11     G:A        1