gpt4 book ai didi

python - 统计多列子串的频率,得到正结果的列名

转载 作者:太空宇宙 更新时间:2023-11-04 01:58:33 25 4
gpt4 key购买 nike

我在 pandas dataframe 中有一些多个患者的测序数据,每个患者都有一列基因型(格式为 x/x:xxx:xxxx 的字符串),患者的数量会有所不同...我需要用这些信息做两件事,

  1. 计算每行每个基因型列中子字符串的频率,例如三名基因型患者:0/1:xxx:xxxx 0/1:xxxx:xxxx 1/1:xxxx:xxxx:xxxx 我需要在新列 df['freq_01' ], 1/1 in row 进入 df['freq_11'] 等的次数有多少。

  2. 我需要为上一步中的每个基因型创建包含样本名称(列的名称)的新列,例如:df['samples_01]= "S1, S2, S4"(每一行)

我可以通过遍历每一行来做到这一点,但我想知道 pandas 是否可以更有效地做到这一点。

原始数据(在我的文件中大约有 100 000 行):

| id | S1      | S2      | S3      | S4      |
|----|---------|---------|---------|---------|
| 1 | 1/1:5:5 | 0/1:3:3 | 0/1:2:2 | 0/1:7:6 |
| 2 | 0/1:3:3 | 1/1:5:5 | 1/1:5:5 | 0 |
| 3 | 0/1:3:3 | 0 | 0/1:3:3 | 1/1:5:5 |

结果应该如何:

| id | S1      | S2      | S3      | S4      | freq_01 | samples_01 |
|----|---------|---------|---------|---------|---------|------------|
| 1 | 1/1:5:5 | 0/1:3:3 | 0/1:2:2 | 0/1:7:6 | 3 | S2,S3,S4 |
| 2 | 0/1:3:3 | 1/1:5:5 | 1/1:5:5 | 0 | 1 | S1 |
| 3 | 0/1:3:3 | 0 | 0/1:3:3 | 1/1:5:5 | 2 | S1,S3 |

最佳答案

您可以使用 Series.str.startswith()将数据帧转换为所有 bool 值的数组,然后计算频率并找到每行上具有 True 值的列名。下面是一个示例代码:

#get a list of columns names required in calculation
cols = df.filter(like='S').columns
#Index(['S1', 'S2', 'S3', 'S4'], dtype='object')

# set up an array with True/False using Series.str.startswith
arr_01 = np.array([ df[c].str.startswith('0/1:') for c in cols ]).T
print(arr_01)
#array([[False, True, True, True],
# [ True, False, False, False],
# [ True, False, True, False]])

# count the True value on row
df['freq_01'] = np.sum(arr_01, axis=1)

# retrieve column names with True values only
df['samples_01'] = [ ','.join(filter(len, x)) for x in np.multiply(arr_01, np.array(cols)) ]
print(df)
# id S1 S2 S3 S4 freq_01 samples_01
#0 1 1/1:5:5 0/1:3:3 0/1:2:2 0/1:7:6 3 S2,S3,S4
#1 2 0/1:3:3 1/1:5:5 1/1:5:5 0 1 S1
#2 3 0/1:3:3 0 0/1:3:3 1/1:5:5 2 S1,S3

要处理更多情况,只需使用for 循环:

cols = df.filter(like='S').columns

for t in [ '01', '11' ]:
subt = t[0] + '/' + t[1] + ':'
arr_t = np.array([ df[c].str.startswith(subt) for c in cols ]).T
df['freq_{}'.format(t)] = np.sum(arr_t, axis=1)
df['samples_{}'.format(t)] = [ ','.join(filter(len, x)) for x in np.multiply(arr_t, np.array(cols)) ]

print(df)
# id S1 S2 S3 S4 freq_01 freq_11 samples_01 samples_11
#0 1 1/1:5:5 0/1:3:3 0/1:2:2 0/1:7:6 3 1 S2,S3,S4 S1
#1 2 0/1:3:3 1/1:5:5 1/1:5:5 0 1 2 S1 S2,S3
#2 3 0/1:3:3 0 0/1:3:3 1/1:5:5 2 1 S1,S3 S4

关于python - 统计多列子串的频率,得到正结果的列名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56252323/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com