如何计算列表中元素在 pandas 中的一行的出现次数
How to count the occurances of elements in list in for a row in pandas
我有一个看起来像这样的 df。它是由 group-by
产生的多索引 df
grouped = df.groupby(['chromosome', 'start_pos', 'end_pos',
'observed']).agg(lambda x: x.tolist())
reference zygosity
chromosome start_pos end_pos observed
chr1 69428 69428 G [T, T] [hom, hom]
69511 69511 G [A, A] [hom, hom]
762273 762273 A [G, G, G] [hom, het, hom]
762589 762589 C [G] [hom]
762592 762592 G [C] [het]
对于每一行,我想计算合子中 het 和 hom 的数量。并创建一个名为 'count_hom' 和 'count_het'
的新列
我试过使用 for 循环,它很慢,而且在更改数据时不太可靠。有没有办法使用 df.zygosity.len().sum() 之类的方法来做到这一点,但仅适用于 het 或仅适用于 hom
使用Series.apply
with List count
:
grouped['count_hom'] = grouped['zygosity'].apply(lambda x: x.count('hom'))
grouped['count_het'] = grouped['zygosity'].apply(lambda x: x.count('het'))
您可以使用 explode
+ groupby
,然后 value_counts
,然后 unstack
:
动态计算所有可能的值
new_df = pd.concat([df, df['zygosity'].explode().groupby(level=[0,1,2,3]).value_counts().unstack(level=4).fillna(0).add_prefix('count_').astype(int)], axis=1)
输出:
>>> new_df
reference zygosity count_het count_hom
chromosome start_pos end_pos observed
chr1 69428 69428 G [T, T] [hom, hom] 0 2
69511 69511 G [A, A] [hom, hom] 0 2
762273 762273 A [G, G, G] [hom, het, hom] 1 2
762589 762589 C [G] [hom] 0 1
762592 762592 G [C] [het] 1 0
您可以通过将 lambda 添加到 agg
来稍微调整您的 groupby
结构,而不是处理 groupby 结果,该 lambda 计算当时每个组的“het”和“hom”值你构建 grouped
:
grouped = (df.groupby(['chromosome', 'start_pos', 'end_pos','observed'])
.agg(reference=('reference', list),
zygosity=('zygosity', list),
count_het=('zygosity', lambda x: x.eq('het').sum()),
count_hom=('zygosity', lambda x: x.eq('hom').sum())))
如果您想从所有列表中创建一个列表,您可以使用以下方法:
cols = ['chromosome', 'start_pos', 'end_pos','observed']
out = df.groupby(cols).agg(**{c: (c, list) for c in df.columns.drop('reference')},
count_het=('zygosity', lambda x: x.eq('het').sum()),
count_hom=('zygosity', lambda x: x.eq('hom').sum()))
我有一个看起来像这样的 df。它是由 group-by
产生的多索引 dfgrouped = df.groupby(['chromosome', 'start_pos', 'end_pos',
'observed']).agg(lambda x: x.tolist())
reference zygosity
chromosome start_pos end_pos observed
chr1 69428 69428 G [T, T] [hom, hom]
69511 69511 G [A, A] [hom, hom]
762273 762273 A [G, G, G] [hom, het, hom]
762589 762589 C [G] [hom]
762592 762592 G [C] [het]
对于每一行,我想计算合子中 het 和 hom 的数量。并创建一个名为 'count_hom' 和 'count_het'
的新列我试过使用 for 循环,它很慢,而且在更改数据时不太可靠。有没有办法使用 df.zygosity.len().sum() 之类的方法来做到这一点,但仅适用于 het 或仅适用于 hom
使用Series.apply
with List count
:
grouped['count_hom'] = grouped['zygosity'].apply(lambda x: x.count('hom'))
grouped['count_het'] = grouped['zygosity'].apply(lambda x: x.count('het'))
您可以使用 explode
+ groupby
,然后 value_counts
,然后 unstack
:
new_df = pd.concat([df, df['zygosity'].explode().groupby(level=[0,1,2,3]).value_counts().unstack(level=4).fillna(0).add_prefix('count_').astype(int)], axis=1)
输出:
>>> new_df
reference zygosity count_het count_hom
chromosome start_pos end_pos observed
chr1 69428 69428 G [T, T] [hom, hom] 0 2
69511 69511 G [A, A] [hom, hom] 0 2
762273 762273 A [G, G, G] [hom, het, hom] 1 2
762589 762589 C [G] [hom] 0 1
762592 762592 G [C] [het] 1 0
您可以通过将 lambda 添加到 agg
来稍微调整您的 groupby
结构,而不是处理 groupby 结果,该 lambda 计算当时每个组的“het”和“hom”值你构建 grouped
:
grouped = (df.groupby(['chromosome', 'start_pos', 'end_pos','observed'])
.agg(reference=('reference', list),
zygosity=('zygosity', list),
count_het=('zygosity', lambda x: x.eq('het').sum()),
count_hom=('zygosity', lambda x: x.eq('hom').sum())))
如果您想从所有列表中创建一个列表,您可以使用以下方法:
cols = ['chromosome', 'start_pos', 'end_pos','observed']
out = df.groupby(cols).agg(**{c: (c, list) for c in df.columns.drop('reference')},
count_het=('zygosity', lambda x: x.eq('het').sum()),
count_hom=('zygosity', lambda x: x.eq('hom').sum()))